perm filename SCNSER.MAC[IP,NET] blob sn#705293 filedate 1983-03-30 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00205 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00032 00002	TITLE SCNSER - TERMINAL SCANNER SERVICE  V1575  SCNSER
C00033 00003	               TABLE OF CONTENTS FOR SCNSER 
C00038 00004		SUBTTL	PARAMETER AND CONFIG DEFINITIONS 
C00040 00005	IFNDEF STDALT,<STDALT==033>		VALUE OF STANDARD ALTMODE  CTY
C00041 00006		SUBTTL	DATA STRUCTURES -- LINTAB AND DSCTAB 
C00044 00007		SUBTTL	DATA STRUCTURES -- LINE DATA BLOCK (LDB)  SCNLDB LDBDDB LDICLR LDBBKU LDBTIP LDBTIT LDBTIC LDBBKC LDBTOP LDBTOT LDBTOC LDBECT LDBECC LDBCLP LDBXNP LDBFLP LDBPBK LDBHPS LDBBCT LDBICT LDBOCT LDICLE
C00048 00008	MORE OF THE PROTOTYPE LINE DATA BLOCK  LDBDCH LDLIDL LDLSTP LDLSSO LDLFCP LDLPIM LDLMIC LDLDLR LDLNEC LDLFCS LDLIMI LDLBKA ZZL
C00051 00009	RH OF LDBDCH - BITS 27-35 = LINE NUMBER, POINTER = LDPLNO  LDRPTY LDRCTY LDROSU LDRDSD LDR274 LDRHLF LDRRMT LDRREM LDRSHC ZZR GTLRDY GTLT37 GTLT35 GTLLCP GTLXON GTLMSK LGLSET DCHSPC
C00054 00010	MORE OF THE PROTOTYPE LINE DATA BLOCK  LDBOFL LDBBYT L1LOFL L1RDEM L1RDEC L1RDEL L1RCHP L1RMIF LDIBCM
C00056 00011	ANOTHER BYTE WORD, FLAGS AT LEFT.  LDBBY2 L2LDEL L2LCCS L2LHD1 L2LHD2 L2LHD3 L2LHD4 L2LHD5 L2LSND L2LTAP L2LHDM L2LCLR L2RXON L2RECS
C00058 00012	IFN FTCIMP,<			[arpa]  LDBIMP LDBQUO
C00060 00013	IFN FTLINK,<			[link]  LDBLNK LDBLKB
C00062 00014	PAGE COUNTER WORD AND PAGE FLAGS  LDBPAG LPLIRM LPLPAG LPLXOF LPLALT LPLBLK LPLSLF LPLSAP LPLDIS LPLPOK LPLACR LPLCLR
C00065 00015	FLAGS AND POINTER TO INTERUPT SERVICE ROUTINES  LDBISR LILCFE LILRSP LILTSP LILAPL LILDBK LILRTC LILTDY ISRTYP ISRDSC ISRCHK ISRINI ISRCHP ISRLPC ISRELE ISRREM ISROFL
C00067 00016	 LDBQUE LDBTTW LDLFSP LDLUAR LDLUAW LDLNAN LDBBCD
C00069 00017	FIVE WORDS FOR REMOTE STATION TERMINAL STATUS  LDBREM LDBCCH LDBVTQ LRLVTM LRLCON LRLSTS LRLSCH LRLDST LRLQED LRLDIP LRLTTO LRLTTW LRLSCG LRLEPW LRLIMO LRLADR LRLXOF LRLCHR LRLDTR LRLDSR LRLDSL LRLATO LRLADL LRL741 LRLTIW LRRSHC LRLCLR LDBTTD LTLXOF LTLRBS LTLCTO LTLAXF LTLACK
C00076 00018	IFN FTMIC,<		IF MIC INCLUDED  LDBMIC LDLCHK LDLMCC LDLOPC LDLERC LDLMCP LDLMCB LDLSIL LDLMMM LDLMTI LDLCL1 LDLMCA LDLRSP LDLRSY LDLLOG LDBLOT LDBLOC LDBLEN
C00079 00019	DISPATCH TABLE FOR PTYS AND CTYS.  CTYDSP ERRDSP LS0000 LS0050 LS0075 LS0110 LS0134 LS0150 LS0200 LS0300 LS0600 LS1200 LS1800 LS2400 LS4800 LS9600
C00081 00020	DATA POINTERS INTO LDB  LDPLCH LDPFCT LDPTTT LDPCPU LDPFLC LDPLNO LDPLNO LDPSVC LDPTIM LDPECK LDPDEM LDPFRM LDPTAB LDPLCT LDPIMI LDPPIM LDPFCS LDPBKA LDPALT LDPDIS LDPOSU PRPOS POHPOS LNPVRG LDPVR1 LDPVR2 LDPCMX LDPRCS LDPWID LDPDSC
C00086 00021	LDPPSZ::POINT	6,LDBPAG(U),29		PAGE SIZE (# OF LINES)  LDPPSZ LDPPCT LDPPFF LDPDEB LDPSPD LDPRTC LDPRSP LDPTSP LDPAPL LDPDBK LDP274 LDPTDY LDPACR LDPSTS LDPSLA LDPDLA LDPRLN LDPELE LDPDRQ LDPEPM LDPRNN LDPRNF LDPCHR LDPADT LDPJOB LDPDST LDP.OP LDP.ER LDPMJN LDIDCM
C00090 00022		SUBTTL	DATA STRUCTURES -- TTY DEVICE DATA BLOCK (DDB)  TTYLST SCNDDB DDBLDB BYTCNT FRCEND IOLBKA CTLSUP IOSBKA IOSTEC IOSNEC IOSFCS
C00093 00023		SUBTTL	TRANSMIT INTERRUPT ROUTINE  XMTINT XMTIN1
C00095 00024	XMTCHR -- ROUTINE TO RETURN THE NEXT CHARACTER TO SEND FROM  XMTHCH XMTCHR XMTCH1 XMTCH2 XMTCH3 XMTCH4
C00098 00025	COUNT UP THE CHARACTERS PHYSICALLY OUTPUT AND RETURN  XMTCNT XMTCN4 XMTCN5 XMTCN6 XMTCNX XMTSPO
C00101 00026	HERE WHEN A SPECIAL CONDITION BIT IS SET IN THE LDB.  THESE BITS  XMTSPC XMTSP1 XMTSTP XMTSSO XMTFLC XMTCIS
C00103 00027	FALL THROUGH TO HERE TO IDLE A LINE.  XMTIDL XMTPSI XMTDMC XMTWAK XMTWK1
C00106 00028	PACKED IMAGE MODE (PIM) TRANSMIT INTERRUPT.  XMTPIM ZAPOU1 SONPJ1 SONPPJ
C00108 00029	HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBMIC IS NON-ZERO  XMTMIC MICLG3
C00111 00030	XMTOK:	MOVE	T2,LDBMIC(U)	GET MIC BITS  XMTOK XMTOK1 ZAPBUF
C00113 00031	HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBXNP IS NON-ZERO.  XMTXOF XMTFIL XMTFI0
C00116 00032	XMTFI3:SCNON  XMTFI3 XMTFI4 XMTFI2 XMTFI1
C00119 00033	HERE WHEN BUFFERED AND FILLER OUTPUT DONE, AND LDBECT IS NON-ZERO  XMTECH XMTEIP XMTEC1 XMTEC2
C00123 00034	CONTINUED FROM PREVIOUS PAGE  XMTEC3 XMTEC4 XMTEC5 XMTEC6 XMTNCP XMTEC8
C00128 00035	ZAPECH:	SETZM	LDBECC(U)	FIX UP  ZAPECH ECHBRK RCVWKQ XMTHDX XMTHDX SETCHP CLRIRM
C00130 00036	TOREQ::	MOVSI	T1,LDLIDL  TOREQ TOPOKE
C00132 00037	ROUTINE TO TAKE AN LDB OUT OF THE 'START OUTPUT' QUEUE  TOTAKE TOTAK1
C00134 00038		SUBTTL	RECEIVE INTERRUPT ROUTINE  RECINT RecImp RECPTY RECINU RECINN
C00138 00039	CONTINUED FROM PREVIOUS PAGE  RECIN0 RECIN1 RECNXI RECIN2 RECQRT RECI2A
C00142 00040	HERE WITH T1=CHARACTER BITS (LH=0 IF NONE), T3=CHARACTER  RECINA RECINB RWARNX RECIN6 RECLN1
C00147 00041	RECIN3:	TLNN	U,LDLLCT	DOES HE WANT UPPER?  RECIN3 RECIN4 SETBKU
C00149 00042	IFN FTHDPX,<  RECHDX RHDERQ RHDERR RHDER2 RHDER1 ECHOUT ECHO ECHOL
C00153 00043	HERE ON RECEIVE INTERRUPT OF A CONTROL-C CHARACTER  RICA RICC RICC RICC2 RICC3 RICC1
C00156 00044	HERE ON RECEIPT OF A ↑D CHARACTER  RICD CD CDSAV
C00157 00045	HERE ON CONTROL H (BACKSPACE) TO DETERMINE HOW TO TREAT  RIBSP
C00158 00046	HERE ON RECEIPT OF A CARRIAGE RETURN (CONTROL M)  RICM RICO RINUL
C00160 00047	HERE ON RECEIVE INTERRUPT OF A CONTROL Q (XON)  RICQ RICQ2A RICQ2
C00162 00048	IFN FTMIC,<			IF MIC  RICP RICB2 RICB3 RICB RICT DOCTLT RICT1
C00165 00049	HERE ON A CONTROL R  RICR RICR1 RICR2
C00168 00050	HERE ON RECEIVE INTERRUPT OF CONTROL S (XOFF)  RICS STPOIP BEATIT RIBUSY BSYTXT GAWTXT
C00170 00051	IFN FTTVP,<  CLRPCT INCPCT CHKPCT
C00172 00052	PACKED IMAGE MODE (PIM) RECEIVE CHARACTER PROCESSING  REPIM REPIM3 RPIM25 REPIM2 REPIM1
C00175 00053	SNDXOF::MOVSI	T1,LPLXOF	GET THE "XOFF HAS BEEN SENT" BIT  SNDXOF
C00176 00054	HERE ON A CONTROL U AT INTERRUPT LEVEL ONLY  RICU RICU1 RICU2 RICU3 RICU4
C00180 00055	RIDLN:	PUSHJ	P,STOPCM	STOP COMCON  RIDLN RIDLN1 DELCHR DELCH3 ZAPIN
C00183 00056	RWARN:	CAIGE	T2,TTIMAX	IF HE IS WAY OVER, OR  RWARN RECHLT RCHLT1 RCHLT2 RECVRG RECVR1
C00185 00057	HERE ON A RUBOUT OR CONTROL W AT INTERRUPT LEVEL  RIDEL RIDELB RIDELX RIDELY RIDELW RIDELZ
C00188 00058	RIDEL5:	PUSHJ	P,TTVID  RIDEL5 RIDEL6
C00190 00059	HERE TO ECHO THE RUBOUT  RIDELA RIDELC RIDELD RIDEL7
C00193 00060	RIDEL8:	MOVNI	T2,-10(T2)	RELATIVE ADDRESS OF BYTE POINTER FOR ERASING  RIDEL8 RIDEL9 RIDEL0 RIDEL4 BACKUP BACKU1 TTVID
C00197 00061	RIDEL1:	SCNON  RIDEL1 RIFRET RIFRT1 RIDEL3 RIDEL2 RIALT RIALTO RIALT2 LNCREC LNRDHC LNREHC
C00201 00062	IFN FTMODM,<			CODE INCLUDED ONLY IF MODEMS SUPPORTED  DSCREC DSROFF
C00203 00063	DSROF1::MOVSI	T1,DSCHWC!DSCSWC!DSCIC2  DSROF1 DSCCAL SIGDSC SIGDS1
C00205 00064	DSRON:  DSRON DSRON1
C00207 00065	CONTINUED FROM PREVIOUS PAGE  DSRN1A DSRON2
C00209 00066	TTFRC1:	AOS	(P)  TTFRC1 TTFORC DSRRNG DSRRN2 DSRRN1 DSCDET
C00212 00067	IFN FTDIAL,<  DSRPND DSRPN1
C00213 00068		SUBTTL	KI10 CONSOLE TERMINAL SERVICE  CTYINT CTYIN CTYOUT
C00214 00069		SUBTTL	KS10 CTY AND KLINIK TERMINAL SERVICE  CT0INT CTYIN1 CTYIN2 CTYIN3 CTYIN4
C00216 00070		SUBTTL	FILLERS AND SIMULATION ROUTINES  SETFLO SETFLI
C00218 00071	CONTINUED FROM PREVIOUS PAGE  SETFL2
C00220 00072	 SETCRF SETCR2 SETCR5
C00224 00073	SETFI1:	TLNN	T1,CHFIL	THIS CHAR NEED FILLERS?  SETFI1 SETFI0 ZFLPOP FLLPOP SETFI2 SETFI3
C00227 00074	CAN ONLY GET HERE FOR ↑U,↑Z OR ↑C. OTHERS NOT STORED IN INPUT BUFFER  SETFI4 SETFI6 SETFI7
C00229 00075	SETFLC -- ROUTINE TO SETUP THE FILLER CLASS FOR A LINE  SETFLC SETXNP SETFLP SETFPT SETFP1
C00231 00076	DISPATCH TO SET FILLERS FOR SOME CHARACTERS  SETFLD FILLH FILLK2 FLLFLG FILXCP FILXCD FILXUP FILXUD FILXOP FILXOD FILXZP FILXZD STFLT2 FILXQD FILXRD FILXSD FILXTD
C00233 00077	FILLKP:					POINTERS FOR BS AND VT  FILLKP FILLHP FILLP2 FILLLP FILLJP FILLP1 FLLCRP FLLCR0 FLLCR1 FLLCR2 FLLCR3 FLLUPA FLLDLR FLLUP1 FLLBSP FLLBS1 FLLBSC FLLCOP FLLCO1 FLLDMY FLLDMP
C00236 00078	VT06BP:	POINT	9,VT06TB  VT06BP VT06EP VTXXBP VTXXEP V100EP HP26EP DM15EP
C00238 00079	VT06TB:	BYTE	(9)	377,377,377,210,240,377,377,377  VT06TB VT06EL VT06E1 VT06E2 VT06E3 VTXXTB VTXXEL VTXXE1 VTXXE2 VTXXE3 V100E1 V100E2 V100E3 HP26E1 HP26E2 HP26E3 DM15E1 DM15E2 DM15E3
C00241 00080	HERE TO GENERATE FILLERS OR SIMULATION FOR HORIZONTAL TAB  FILLI FILL1 FILLI1 FILLJ FILLK FILLK1 SCCHPJ
C00244 00081	FILLL:	TLNE	U,LDLFRM	THIS LINE HAVE FORM MOTION?  FILLL FILLL1 FILLM FILLM1 RETYPE RETYPL STOPCM
C00248 00082	DATA SENT OUT AS FILLERS  FILLER FILLRX FILLRY FILLRZ KSPACE KLINEF FILLIP FLSLD0 FLSKD0 FLSLD1 FLSKD1 FLBPXF FLLKSP FLLLSP FLBLXF FLPBEL FLPXOF FLPPXF FLLXON FLPXON
C00251 00083		SUBTTL	TIMING ROUTINE  SCNSEC SCNSIL
C00253 00084		JRST	[PUSHJ P,TOREQ	REQUEUE SO OUTPUT STARTS  SCNSIN SCNSIS
C00255 00085	IFN FTMODM,<  DSCSEC DSCSLP DSCSC2 DSCSNY DSCSC1
C00258 00086	DSCSC3:	MOVSI	T3,DSCBLI	SET FOR BLIND BIT  DSCSC3 DSCSDF DSCWAK DSTIMP DSTMPL
C00260 00087	SUBROUTINE TO TIME THE IMAGE MODE INPUT STATE, SET END OF FILE IF  SCSIMG SCSIM2 SCSIM1
C00263 00088	OUTPUT SERVICE ROUTINE FOR CTY  CTYSTO CTYTYO CTYTY1 KLITYO
C00265 00089	ROUTINE TO ADJUST HORIZONTAL POSITION COUNT FOR CHARACTER TO  ADJHP ADJHP3 ADJHP2 ADJHP1 T23PPJ
C00267 00090	HPOS -- SUBROUTINE TO FETCH THE CURRENT HORIZONTAL POSITION ON A LINE  HPOS SCNBOL
C00268 00091	ROUTINE TO SUPPRESS BLANK LINES  BLSUPI BLSUPO
C00270 00092	SUBROUTINE TO WAKE UP JOB IF IT IS IN TERMINAL INPUT WAIT. CALL WITH  RCVWAK WAKJBR TTWAKE TTWAKI TTWAKO TTWAKB TTWAKX FULLCQ
C00273 00093	WAKJB:	PUSH	P,T2		SAVE AC'S  WAKJB HIBTTY HIBSET HIBTTL
C00275 00094	TABLE OF CONTROL CHARACTERS - LH=BITS, RH=DISP ADDR ON RCV INT  CHBRK CHUAE CHFIL CHALT CHRIA CHCRET CHCNC CHDEL CHFILO CHCRE CHVPOS CHEPAR CHDELW CHPUNC CHXPIH CHSUSP CHXPIH CHSUSP CHSPO CHTABL
C00285 00095	TTPWID:	POINT	8,TCRTAB(T1),7	POINTER TO TERMINAL WIDTH  TTPWID TTPPSZ TTPFLC TTPFRM TTPTAB TTPLCT TTPALT TTPDIS X1 X2 X3 X4 X5 CTCTAB TCRTAB
C00289 00096	ROUTINE TO CHECK FOR A SPECIAL CHARACTER AND SET T1 TO ITS DESCRIPTOR  SPCHEK PEVEN8
C00291 00097		SUBTTL	CHUNK HANDLERS  NEWCKO NWCKO1 NEWCKI
C00294 00098	NEWCKS -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS  NEWCKS CL0STP RCCCHK
C00296 00099		SUBTTL	CHUNK HANDLERS -- ALLOCATION AND DEALLOCATION  GETCKZ GETCHK FRECHK
C00298 00100		SUBTTL	CHUNK HANDLERS -- CLEAR BUFFERS  TSETBI TSETI2 TSETBO TSETB1 TSETB2 RCCSTP
C00301 00101		SUBTTL	UUO LEVEL ROUTINES FOR BUFFERED I/O  SCNDSP
C00302 00102	INPUT UUO PROCESSOR - CALLED FROM UUOCON ON INPUT UUO, DDB SET UP  TTYIN TTYINA TTYIN0 TTYIN5
C00305 00103	TTYIN1:	PUSHJ	P,TYICC		GET A CHARACTER  TTYIN1 TTYIN2 TTYIN3 TTYINC TTYIN8 TTYINX TTYINE TTYIN9
C00308 00104	OUTPUT UUO CALLS HERE  TTYOUT TTOUT0 TTOUT1
C00311 00105	CONTINUED FROM PREVIOUS PAGE  TTOUT2 TTOUT4 TTOUT5 TTOUT6 TTOUT3 TTOUT7 TTOUT8
C00314 00106	TTMORE::PUSHJ	P,SAVE2##	SAVE P1-P2  TTMORE MORE10 MORE20 MORE30 MORE40 MOR405 MORE41
C00318 00107	MORE50:	DPB	P1,BYTCNT	SAVE BYTE COUNT  MORE50 CKROOM
C00320 00108		SUBTTL	DDT MODE CALLI'S  DDTIN DDTINL DDTINX DDTOUT
C00323 00109		SUBTTL	TTCALL AND TRMOP. -- TTCALL DISPATCH  TTYUUO TTUUA TTUUB TTUUC TTUUD TTUUE
C00325 00110	THE FOLLOWING TABLE IS USED TO PRE-CHECK AND DISPATCH THE TTCALL'S.  TC.ADC TC.USR TC.USW TC.ATW TC.ATR TC.ECS TTUUOT
C00328 00111		SUBTTL	TTCALL AND TRMOP. -- OUTCHR AND IMAGE OUTCHR  ONEOUT ONEOU1 IONEOU
C00330 00112		SUBTTL	TTCALL AND TRMOP. -- OUTSTR AND RESCAN  OUTSTR OUTST3 OUTST6 OUTST5 OUTST2 OUTST1 OUTST4 TRESCU
C00333 00113		SUBTTL	TTCALL AND TRMOP. -- SKPINL AND SKPINC  SKPINL SKPINC NOCTRO STCTRO
C00335 00114		SUBTTL	TTCALL AND TRMOP. -- GETLIN  GL.ITY GL.CTY GL.DSP GL.DSL GL.HDP GL.REM GL.RBS GL.LIN GL.SLV GL.LCM GL.TAB GL.LCP GL.PTM GETLIN GETLN1 GETLNZ
C00339 00115		SUBTTL	TTCALL AND TRMOP. -- SETLIN, INCHSL, INCHWL, INCHRS & INCHRW  SETLIN L2PXON SETLP1 INCHRS ICS3 INCHSL INCHWL ICW1 INCHRW
C00342 00116		SUBTTL	TTCALL AND TRMOP. -- TRMNO. UUO  TRMNO
C00344 00117		SUBTTL	TTCALL AND TRMOP. -- TRMOP. DISPATCH  TRMOP TRMNRM
C00347 00118	CONTINUED FROM PREVIOUS PAGE  TRMO1 CHKRED CHKWRT CHKDDB
C00349 00119	HERE IF REQUESTED FUNCTION NOT FROM 1 THRU TOPLN0-1  TOPRSQ TOPSET TOPST1 TOPST2 TOPST3
C00351 00120	TOPST4:	TLNN	T2,(TOP.IF)	THIS FUNCTION ILLEGAL FOR FRCLIN?  TOPST4 TOPST5 TOPTFE
C00353 00121	TOPRED:	CAIL	T1,TOPLN1	LEGAL ITEM NUMBER?  TOPRED TOPRD1 TOPOIP TOPHPS TOPHPR
C00355 00122	ROUTINE TO HANDLE FUNCTION 1041  TOPTTC TOPTT1 TOPSUP TOPSU2 TOPSU5 TOPCCT
C00357 00123	SUBROUTINE TO CHECK FOR READ PRIVS  TREDOK TWRTOK MYTTY MYTTY2 MYTTY1
C00360 00124	ERROR RETURNS 
C00361 00125	TOPTB0 - TRMOP. ACTION FUNCTIONS LESS THAN 1000   TOP.RP TOP.WP TOP.NF TOP.MC TOP.MR TOPTB0 TOPLN0
C00365 00126	TOPTB1 - TRMOP. READ/SET FUNCTIONS GREATER THAN 1000  TOP.SA TOP.PS TOP.PE TOP.RT TOP.IF TOPTB1 TOPLN1
C00371 00127	TOPSYR:	POINT	6,TOPTB1(P1),5	POINTER TO RANGE TABLE INDEX  TOPSYR TOPSRT
C00372 00128		SUBTTL	TTCALL AND TRMOP. -- SKIPS AND CLEARS  TOPSIP TOPSOP TOPCIB TOPCOB TOPIIC TOPDSE TOPDSF TOPDSC TOPDSS
C00374 00129		SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O  TOPOUC TOPMDP TOPOUS TOPOU1 TOPOIC
C00376 00130	INPUT A CHAR  TOPISC TOPINC TOPIIC TOPRES
C00377 00131		SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O SUBROUTINES  TOPDDB TOPDD2 TOPDD1
C00379 00132		SUBTTL	TTCALL AND TRMOP. -- TRMOP. DATASET FUNCTIONS  TOPDSE TOPDSF TOPDF1 TOPDSS
C00382 00133	IFE FTDIAL,<  TOPDSC NETDSS NETDSE NETDSF NETDSC NETISR
C00383 00134	IFN FTDIAL,<  TOPDSC TOPDC1 TOPDC2 TOPDC3
C00386 00135	IFN FTCAFE!FTKS10,<  TOPABR TOPELE
C00387 00136		SUBTTL	TTCALL AND TRMOP. -- TYPE INTO TTY ON BEHALF OF A USER  TOPMTY TOPMT1 TOPMT2 TOPTYP TOPMT3
C00390 00137		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  SET/CLEAR LDBMIC  TOPMCL TOPMST TOPMS1
C00392 00138		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  RETURN MIC STATUS  TOPMGT TOPMG1
C00395 00139		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  READ ERROR RESPONSE TEXT  TOPMRS TOPMR1 TOPMR2 TOPMR3
C00397 00140		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  LOG ALL TERMINAL OUTPUT  TOPMLG TOPML1 TOPML3 TOPML2
C00399 00141		SUBTTL	TTCALL AND TRMOP.  --  MIC  --  MISCELLANEOUS MIC SUBROUTINES  MICLGC MICLG1 MICLG2 MICADC MICAD1
C00401 00142	STILL FTMIC  MICPOS MICPS1 MICPS2 MICPS4 MICPS3
C00403 00143	STILL FTMIC  MLOGOF MICWAK MICWA1 MICECH MICRIC MICPRC
C00405 00144	STILL FTMIC  MICRIA PTYMCK FRCSET
C00407 00145		SUBTTL	SUBROUTINES FOR I/O  TYIS TYI TYICC TYICC2 TYICC3 TYICC4
C00410 00146	CONTINUED FROM PREVIOUS PAGE  TYIC TYICCZ
C00413 00147	SUBROUTINE TO DISCARD A COMMAND FROM INPUT BUFFER IF L2RECS STILL ON  TYIEAT TYIL TYID
C00415 00148	HERE ARE THE ROUTINES TO PERFROM VARIOUS "TTY INPUT" FUNCTIONS  CTIGNC CTIGLC CTISLC CTIGBP CTISBP CTICOM COMTIV CCTYI CCTYI1
C00418 00149	SUBROUTINE TO SEE IF A CONTROL C SHOULD BE ACTED ON OR STORED.  CNCCHK CNCCK1 CLRIIQ CLRIMI CLRIM1
C00420 00150	ROUTINE TO PUT TERMINAL INTO MONITOR COMMAND MODE. DON'T CALL THIS  CNCMOD CNCMO2 COMQ
C00423 00151	ROUTINE TO MAKE THIS TERMINAL VISIBLE TO COMMAND DECODER, IF AT COM LEVEL  COMSET COMST1 COMSTF CMDSET CMDCLR
C00425 00152	TTFCOM::				FORCED COMMAND TABLE  TTFCOM TTFCXC TTFCXD TTFCXH TTFCXR TTFCXK TTFCXI TTFCXJ TTFCXU TTFCXT TTFCXW TTFCXL TTFCXS TTFCXF TTFCXG TTFCXX TTFCML MTTFCM
C00427 00153		SUBTTL	COMMAND LEVEL ROUTINES  TTYCOM TTYCM0 TTYCM1 TTYCM2 TTYCM3 TTYCM4 TTCM4A TRESCN TRESC1
C00430 00154	DO FORCED COMMANDS OR CLEANUP 1ST, THEN FORCED KJOBS, THEN TYPED-IN COMMANDS  TTYCM7 TTYCM5 TTYCM6
C00432 00155	TTKJOB::PUSHJ	P,CNCMOD	CONSOLE TO COMMAND LEVEL  TTKJOB TTHALT
C00434 00156	ROUTINES TO ATTACH TERMINAL TO A JOB  TTYATT TTYAT1
C00437 00157	TTYATI::  TTYATI TTYAT2 TTYAT3
C00440 00158	CONTINUED FROM PREVIOUS PAGE  TTYAT4 TTYAT5 TTYAT6
C00442 00159	SUBROUTINE TO LOOK FOR POSSIBLE LINE ALREADY ATTACHED TO TARGET JOB  TTYISA TTYIS1
C00445 00160	ROUTINE TO DETACH TERMINAL FROM A JOB.  TTYDTC TTYDET PTYDTC PTYDET TTYKLQ
C00448 00161	SUBROUTINE TO DISCONNECT A TERMINAL FROM A JOB WITHOUT SETTING TERMINAL TO MONITOR LEVEL  TTYDT1 TTYDTX SIGDET DETCHK DETCH1
C00451 00162	ROUTINE TO RELEASE A TTY DDB. CALL WITH DDB SET UP.  TTYREL TTYRL0 TTYRL1 TTYRL2
C00453 00163	ROUTINE TO CLEAR A TTY DDB AND MAKE IT AVAILABLE TO THE POOL  TTYKIL TTYKL1
C00456 00164	SUBROUTINE CALLED ON RESET FROM UUOCON  TTYRES TTYRSA TTYRSC TTYRSB TTYRS1 TTYRS2
C00459 00165	SUBROUTINE TO RETURN ONE CHARACTER FROM THE INPUT BUFFER. CHARACTER  COMTYI COMTI1 COMTIX USEARO COMTYO
C00462 00166	ROUTINE TO SWITCH TERMINAL TO USER PROGRAM LEVEL AND START USER RUNNING  TTYUSW TTYUSR TTYUS1 TTYSTC TTYSTR
C00465 00167	HERE AT COMPLETION OF A COMMAND  TTYCMR TTCMR1
C00468 00168		SUBTTL	SUBROUTINES FOR COMCON OR UUO LEVEL  TYO TYO7W TYO9W TYOX TYO9M TYO9A LnkCpy
C00472 00169	TYOVRG:	SCNOFF			NO INTERRUPTS  TYOVRG TYOVR1 TYONFC MICLGX TYOOBF
C00474 00170	SUBROUTINE TO SETUP A BYTE COUNT AND POINTER TO A USER'S BUFFER  SRLPTR
C00476 00171	SUBROUTINE FOR COMMAND LEVEL OUTPUT  CCTYO CCTYO9
C00477 00172		$LOW			MUST BE IN THE LOW SEGMENT FOR ONCE-ONLY  CTYTYP CTYTYL CTYPAR
C00479 00173	SUBROUTINE FOR ERROR MESSAGE TO CTY DURING PARITY ERROR STOP  CTYWAT
C00481 00174		$HIGH			BACK TO THE HIGH SEGMENT  TTYCPT OPRFIL OPRFI1 OPRFI1 OPRFI1 OPRFI2 LCPOPJ
C00484 00175	ROUTINE TO FIND A FREE TTY DEVICE DATA BLOCK  DDBSRC DDBSR0 DDBSRA DDBSR1
C00487 00176	ROUTINE TO FIND A TTY DDB WHICH IS ATTACHED TO, I.E.  TTYSRC
C00489 00177	ROUTINE CALLED WHEN DEVSRC CAN'T FIND DEVICE XXX (IN T1), AND  GETDDB GETDB5 CHKFLN
C00492 00178	SUBROUTINE TO PUT PHYSICAL NAME INTO T2 FOR U WHOSE LDB IS IN U  TTYNAM
C00493 00179	SUBROUTINE TO FIND LDB FOR A PHYSICAL NAME, IF ITS A TTY  TTYPHX TTYPH4 TTYPH2 TTYPH1 TTYPHY TTYPHZ TTYALL
C00496 00180	SUBROUTINE TO FIND TTY FOR A JOB IN J (TTYFND) OR FOR  TTYFNU TTYFND TTYFNX TTYFUW TOWAIT TOWAT1 TOWAT2 PTSTRT
C00500 00181	SUBROUTINE TTYERP TO FIND TTY DDB FOR A MONITOR ERROR MESSAGE.  TTYERP TTYERO TTYERX CKATTI CKATT0 CKATIW CKATI1 CKATI2
C00503 00182	CKATOU:	PUSHJ	P,CKATTO	FIRST MAKE SURE A LINE ATTACHED TO DDB  CKATOU CKATTO CKATOW CKATO1 UUOLDB UUOLD1 UUOLD2
C00508 00183	HERE FROM UUOCON WHEN A TTY HAS BEEN INITED.  TTYOPN
C00509 00184	TWAITI  --  WAIT FOR INPUT (CHARACTER OR LINE MODE)  TWAITI TWAITL TWATL1 TWATLK TWAITC
C00512 00185	TTICHK  --  CHECK IF ANY INPUT IS AVAILABLE, LINE OR CHARACTER MODE  TTICHK TTLCHK TTLCK2 TTCCHK
C00515 00186	SUBROUTINE TIWAIT TO WAIT FOR SOME INPUT, AND SEND XON IF NEEDED.  TIWAIT STRTDC STRTDL STRTDE
C00518 00187	ROUTINE TO CHECK IF AN XOFF HAS BEEN SENT OUT  CHKXON CHKXN1 CLRTI CLRTI1
C00520 00188	IFE FT2741,<  UNLKBD UNLKBD UNLKB1 TTYOFE
C00523 00189	ROUTINE TO PUT SIXBIT NAME IN DEVNAM(DDB), AND TO SET PUNIT.  SCNNAM SCNNMR
C00525 00190	IFN FTNET,<  SETSTA FNDSTA DDBRL DDBRL1 STDOPR
C00527 00191		SUBTTL	ROUTINES FOR PTY  CNTRLO PTYPUT PtyNCP PTYINA
C00530 00192	CONTINUED FROM PREVIOUS PAGE  PTYPT1
C00532 00193	MORE OF PTYPUT. SPECIAL CODE FOR CONTROL C  PTYCC PTYCC4 PTYCC1 FLPCNO PTYCT
C00534 00194	SUBROUTINE TO SET DEFAULT TERMINAL CHARACTERSTICS  SETTTC SETTT1
C00536 00195	TWO SUBROUTINES TO INITIALIZE THE LDB. LDBCLR SETS UP THE BITS FROM  LDBCLR LDBINI
C00539 00196	CONTINUED FROM PREVIOUS PAGE  LDBIMI
C00542 00197		subttl	ScnSer support for ARPAnet 
C00543 00198	[arpa]	still in IFN FtCImp  SCNMIN SCNMN1
C00544 00199	[arpa]	still in IFN FtCImp  DSCCLR DSCCL1
C00547 00200	[arpa]	still in IFN FtCImp  TTYIMP TTYIM1 TTYIM2
C00549 00201	[arpa]	still in IFN FtCImp  TTIMPI
C00550 00202	[arpa]	still in IFN FtCImp  TTYTTI
C00551 00203	[arpa]	still in IFN FtCImp  TTYXMT
C00553 00204	[arpa]	still in IFN FtCImp  SETECH SETNEC
C00555 00205		SUBTTL	IMPURE DATA  ECHCNT TTBASE DSCNUM .GTSCN %SCNRI %SCNXI %SCNEI TIWRNN %SCNAL RPIMWN TTFTAK TTFPUT SCNMXL TIWRN1 SCNEND
C00557 ENDMK
C⊗;
TITLE SCNSER - TERMINAL SCANNER SERVICE  V1575 ;⊗ SCNSER
SUBTTL R CLEMENTS/RCC/DAL/PMW/EJW/WRS	22 JUL 80
	SEARCH	F,S
IFN FTNET,<SEARCH NETPRM>
	$RELOC
	$HIGH

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
XP VSCNSR,1575
ENTRY SCNSER
SCNSER::


;               TABLE OF CONTENTS FOR SCNSER ;⊗
;
;
;                        SECTION                                   PAGE
;    1. PARAMETER AND CONFIG DEFINITIONS..........................   2
;    2. DATA STRUCTURES
;         2.1   LINTAB AND DSCTAB.................................   4
;         2.2   LINE DATA BLOCK (LDB).............................   5
;    3. MACROS TO MANIPULATE TERMINAL BUFFER STREAMS..............  13
;         3.3   TTY DEVICE DATA BLOCK (DDB).......................  16
;    4. TRANSMIT INTERRUPT ROUTINE................................  17
;    5. RECEIVE INTERRUPT ROUTINE.................................  30
;    6. KI10 CONSOLE TERMINAL SERVICE.............................  55
;    7. FILLERS AND SIMULATION ROUTINES...........................  56
;    8. TIMING ROUTINE............................................  68
;    9. CHUNK HANDLERS............................................  84
;   10. CHUNK HANDLERS
;        10.1   ALLOCATION AND DEALLOCATION.......................  85
;        10.2   CLEAR BUFFERS.....................................  86
;   11. UUO LEVEL ROUTINES FOR BUFFERED I/O.......................  87
;   12. DDT MODE CALLI'S..........................................  94
;   13. TTCALL AND TRMOP.
;        13.1   TTCALL DISPATCH...................................  95
;        13.2   OUTCHR AND IMAGE OUTCHR...........................  97
;        13.3   OUTSTR AND RESCAN.................................  98
;        13.4   SKPINL AND SKPINC.................................  99
;        13.5   GETLIN............................................ 100
;        13.6   SETLIN, INCHSL, INCHWL, INCHRS & INCHRW........... 101
;        13.7   TRMNO. UUO........................................ 102
;        13.8   TRMOP. DISPATCH................................... 103
;        13.9   SKIPS AND CLEARS.................................. 111
;        13.10  TRMOP. I/O........................................ 112
;        13.11  TRMOP. I/O SUBROUTINES............................ 113
;        13.12  TRMOP. DATASET FUNCTIONS.......................... 114
;   14. BYTE POINTERS INTO THE USER'S LDBMIC WORD................. 118
;   15. TYPE
;        15.1   - TYPE A STRING ON BEHALF OF A USER............... 119
;   16. CLEAR/SET
;        16.1   - CLEAR DOWN LDBMIC/SET UP LDBMIC................. 120
;   17. GET
;        17.1   GET THE STATUS FROM THE USERS LDBMIC WORD......... 121
;   18. RESPONSE
;        18.1   - RECORD AN ERROR MESSAGE......................... 122
;   19. LOG
;        19.1   - RECORD ALL UUO LEVEL OUTPUT..................... 123
;   20. SUBROUTINES CALLED FROM SCNSER AND OTHER PLACES........... 124
;   21. SUBROUTINES FOR I/O....................................... 128
;   22. COMMAND LEVEL ROUTINES.................................... 136
;   23. SUBROUTINES FOR COMCON OR UUO LEVEL....................... 149
;   24. ROUTINES FOR PTY.......................................... 169
;   25. IMPURE DATA............................................... 173
	SUBTTL	PARAMETER AND CONFIG DEFINITIONS ;⊗

XP STTYBF,20

;DATASET TRANSACTION CODES FROM SCNSER TO/FROM XXXINT'S

XP DSTOFF,1		;DSCREC OR DSCTYP
XP DSTON,2		;DSCREC OR DSCTYP
XP DSTRNG,3		;DSCREC
XP DSTREQ,3		;DSCTYP
XP DSTINI,4		;TO AND FROM. SENDING COMPUTER WAS RESTARTED.
XP DSTSTS,5		;REQUEST DATA SET STATUS
XP DSTCRQ,10		;CALL REQUEST TO MODEM. WANT TO DIAL OUT.
XP DSTPND,20		;PRESENT NEXT DIGIT, TO AND FROM.
; NOTE - TO MODEM, 20-37 MEAN SEND DIGIT N-20
; WHERE DIGIT 17 MEANS END OF NUMBER (TO BOTH HARDWARE AND SOFTWARE)
; AND DIGIT 16 MEANS 5-SECOND DELAY TO SOFTWARE, FOR SECOND DIAL TONE.
XP DSTNAC,40		;NO ACTION -SYSINI (ONLY USER OF DSTREQ) SHOULD
			; NOT MODIFY LINE STATUS CODES (CARRIER ON/OFF)

;LINE CONTROL TRANSACTION CODES

XP LNTEHC,1	;ENABLE HUNG CHECK
XP LNTDHC,2	;DISABLE HUNG CHECK
IFNDEF STDALT,<STDALT==033>		;VALUE OF STANDARD ALTMODE ;⊗ CTY
IFNDEF VTAB,<VTAB==10>			;VERTICAL TAB SPACING (MUST BE POWER OF 2)

ND	TTIBRK,↑D132			;MAX CHARS BEFORE BREAK CONDITION
ND	TTIWRN,TTIBRK+↑D40		;MAX CHARS BEFORE WE SEND AN XOFF
ND	TTIMAX,↑D300			;MAX CHARS BEFORE WE START TO SSIN??

IFNDEF FTMLOG,<XP FTMLOG,-1>		;NON-ZERO TO INCLUDE MIC LOG CODE

;SIZE OF CHUNKS

XP IMGTIM,↑D10		;MUST FIT IN LDPTIM FIELD. HUNG TIME FOR IMI


;HARDWARE PARAMETERS OTHER THAN THOSE IN THE XXXINT ROUTINES

CTY=120		;HARDWARE DEVICE NUMBER OF THE KA10 CONSOLE TERMINAL
	SUBTTL	DATA STRUCTURES -- LINTAB AND DSCTAB ;⊗


;DATA STRUCTURES IN COMMON

;LINTAB:	BLOCK # OF LINES INCLUDING SCANNER,CTY AND PTY'S
;EACH WORD=	RH= LDB ADR
;		LH13-17=0 (FOR @ LINTAB)
;		LH 0-12 ARE COPIED INTO LDBDCH PERMANENT BITS BY LDBCLR
;		POINTER = LNPVRG

;DSCTAB:	BLOCK # OF DATASETS NEEDING TIMING
;		RH= LINKED TERMINAL LINE NUMBER FOR DATA
;		LH= TIME IN 14-17, ALSO DSCHWC,DSCSWC,DSCFAI

IFN FTMODM,<
XP DSCHWC,400000	;WHEN LAST HEARD FROM, THE HARDWARE CARRIER WAS ON
XP DSCSWC,200000	;THE SOFTWARE CONSIDERS THE CARRIER TO BE ON OR
			; TO BE COMING ON IMMINENTLY
XP DSCFAI,100000	;CARRIER WENT OFF, BUT MAY BE BRIEF FAILURE
			; EXCEPT FOR GPO 2B MODEM, MUST QUIT IMMEDIATELY
XP DSCNCR,040000	;NEW CARRIER FLAG, ON FOR FRACTION OF SECOND FOR CLOCK SYNC
XP DSCBLI,020000	;BLIND FLAG - IGNORE EVERYTHING FOR 1 SEC AFTER CARRIER ON
XP DSCDLW,010000	;DIALLER WAIT. WAITING FOR RESULTS FROM DIALLER
XP DSCDLF,004000	;DIALLER FAIL. UNSUCCESSFUL DIALLER ATTEMPT
XP DSCDLC,002000	;DIALLER COMPLETE. SUCCESSFUL DIALLER ACTION.
XP DSCEON,001000	;END OF NUMBER. SENT ALL DIGITS TO DIALLER.
XP DSCTMM,77		;TIME MASK. MUST AGREE WITH DSTIMP POINTER.

;DEFINITIONS FOR INITIALIZATION ROUTINE IN SYSINI

XP DSCICL,DSCHWC!DSCSWC!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON!DSCTMM
XP DSCIC1,DSCHWC!DSCSWC
XP DSCIC2,DSCTMM!DSCFAI!DSCDLW!DSCDLF!DSCDLC!DSCEON

> ;END OF FTMODM CONDITIONAL
	SUBTTL	DATA STRUCTURES -- LINE DATA BLOCK (LDB) ;⊗ SCNLDB LDBDDB LDICLR LDBBKU LDBTIP LDBTIT LDBTIC LDBBKC LDBTOP LDBTOT LDBTOC LDBECT LDBECC LDBCLP LDBXNP LDBFLP LDBPBK LDBHPS LDBBCT LDBICT LDBOCT LDICLE

;PROTOTYPE LINE DATA BLOCK FOR A TTY (OR PTY) LINE

SCNLDB::
PHASE 0

LDBDDB::!XWD	ZERO5,0	;ADDRESS OF LINE'S ATTACHED DDB, IF ANY
XP LDBCMR,400000	;SIGN BIT OF LDBDDB IS COMMAND REQUEST BIT
			; MUST BE IN WORD ZERO, FOR @U, 13-17 MUST BE ZERO
XP LDBCMF,200000	;COMMAND FORCED. MEANS TYI ATE A CONTROL C
			; WHICH WAS DESTINED FOR COMCON, OR SOME OTHER COMMAND
			; IS TO BE FORCED, VIA LDPCMX. MUST BE IN SAME
			; WORD AS LDBCMR
XP LDBCMK,100000	;FORCING KJOB COMMAND
XP LDBDET,40000		;JOB DETACHED FROM THIS LINE DURING COMMAND
			;PROCESSING.  FORCE CLEANUP OF JOB/COMMAND
			;AT NEXT TICK.
			;BITS 9-12 ARE INDEX FOR FORCED COMMAND, 
			; POINTER = LDPCMX

LDICLR::!		;ON RESTART, START CLEARING HERE
LDBBKU:!0		;COPY OF LDBTIP AT LAST BREAK RECINT
LDBTIP::!0		;T2 TO PUT CHARACTERS IN INPUT BUFFER
LDBTIT::!0		;T2 TO TAKE CHARACTERS FROM INPUT BUFFER
LDBTIC::!0		;COUNT OF ECHOED CHARACTERS IN INPUT BUFFER
LDBBKC::!0		;COUNT OF BREAK CHARACTERS IN INPUT BUFFER
LDBTOP::!0		;T3 TO PUT CHARACTERS IN OUTPUT BUFFER
LDBTOT::!0		;T2 TO TAKE CHARACTERS FROM OUTPUT BUFFER
LDBTOC::!0		;COUNT OF CHARACTERS IN OUTPUT BUFFER
LDBECT::!0		;T2 TO TAKE CHARACTERS FROM INPUT FOR ECHOING
LDBECC::!0		;COUNT OF CHARACTERS TO ECHO
LDBCLP::!0		;COMMAND LINE POINTER (FOR COMCON)
LDBXNP::!0		;XON CLASS CHARACTER POINTER FOR OUTPUT
LDBFLP::!0		;FILLER CHARACTER POINTER FOR OUTPUT
LDBPBK::!0		;WORD OF UP TO 4 BREAK CHARACTERS (8 BIT)
			;FOR PACKED IMAGE MODE (PIM); SET WITH TRMOP 2037
LDBHPS::!0		;HORIZONTAL POSITION COUNTER.  COUNTS UP FROM
			;MINUS CARRIAGE WIDTH TO ZERO.
IFN FTRSP!FTACCT,<
LDBBCT::!0		;TOTAL COMMAND,,BREAK CHARACTER COUNT
LDBICT:!0		;TOTAL INPUT CHARACTER COUNT
LDBOCT:!0		;TOTAL OUTPUT CHARACTER COUNT
> ;END IFN FTRSP!FTACCT

LDICLE==:.-1		;ON RESTART, CLEAR THRU HERE
;MORE OF THE PROTOTYPE LINE DATA BLOCK ;⊗ LDBDCH LDLIDL LDLSTP LDLSSO LDLFCP LDLPIM LDLMIC LDLDLR LDLNEC LDLFCS LDLIMI LDLBKA ZZL
LDBDCH::!0		;DEVICE CHARACTERISTICS BITS

;BITS IN LH OF LDBDCH (CARRIED IN LH OF U DURING INTERRUPT ROUTINE)
;ORDER OF FIRST SEVERAL BITS IS IMPORTANT  --  SEE XMTSPC!

LDLIDL==:400000		;LINE IS IDLE.  IF CLEAR, WE ARE EXPECTING
			;A TRANSMIT INTERRUPT
			; MUST BE SIGN BIT.
LDLSTP==:200000		;OUTPUT WAS STOPPED BY CTRL/S
LDLSSO==:100000		;SCNSER STOPED OUTPUT. (HIT A TTY PAGE N BREAK)
LDLFCP==:040000		;A FORCE CHARACTER OR FILLERS ARE PENDING
			;NOTE! THIS BIT CAN BE SET WITH OUT FEAR IF ONE
			; WISHES TO HAVE XMTRDY SKIP RETURN, BUT IS NOT SURE
			; THAT A CHAR IS AVAILABLE. (SEE TTYDRQ)
LDLPIM==:020000		;TERMINAL WAS OPENED IN PIM MODE
LDLMIC==010000		;LDBMIC IS NON-ZERO
LDLDLR==004000		;SUPPRESS DOLLAR SIGN ON ALTMODES.
LDLNEC==:002000		;NO ECHO, DUE TO PROGRAM
LDLFCS==:001000		;LINE INITED IN FULL CHAR SET MODE
LDLIMI==:000400		;IMAGE INPUT (KEEP NULLS)
XP LDLCOM,000200	;LINE IS AT COMMAND LEVEL
LDLBKA==:000100		;BREAK ON ALL CHARACTERS (DDTIN, TTCALL)

;*** BEGINNING OF GROUP OF BITS POINTED TO BY LDPVR1 ***
;*** BEGINNING OF 4 BITS POINTED TO BY GETLP1 FOR GETLIN ****
XP LDLSLV,000040	;SLAVE. THIS TERMINAL MAY BE ASSIGNED.
XP LDLLCT,000020	;LOWER CASE TRANSLATE TO UPPER
XP LDLTAB,000010	;LINE ACCEPTS TABS, NOT SPACES.
XP LDLLCP,000004	;LOCAL COPY (NO ECHO)
;*** END OF BITS POINTED TO BY GETLP1 ***
XP LDLFRM,000002	;LINE ACCEPTS FF AND VT (ELSE USE LF'S)
XP LDLNFC,000001	;NO FREE CARRIAGE RETURN AT 72 COLUMNS
;*** END OF GROUP FOR LDPVR1 ***
XP LDLECH,LDLNEC!LDLBKA!LDLLCP

;BITS TO BE CLEARED ON A 140 RESTART
ZZL==LDLIDL+LDLIMI+LDLSTP+LDLSSO+LDLNEC+LDLFCP+LDLDLR+LDLBKA+LDLPIM+LDLMIC+LDLFCS
XP LDLIIF,LDLIMI+LDLFCS		;IMAGE INPUT OR FULL CHAR SET MODE
;RH OF LDBDCH - BITS 27-35 = LINE NUMBER, POINTER = LDPLNO ;⊗ LDRPTY LDRCTY LDROSU LDRDSD LDR274 LDRHLF LDRRMT LDRREM LDRSHC ZZR GTLRDY GTLT37 GTLT35 GTLLCP GTLXON GTLMSK LGLSET DCHSPC

LDRPTY==:400000		;PSEUDO-TERMINAL
LDRCTY==:200000		;CONSOLE TERMINAL
;*** START OF GROUP OF BITS POINTED TO BY LDPVR2 ***
LDROSU==:100000		;OUTPUT SUPPRESS (↑O)
LDRDSD==:040000		;DATASET DATA LINE
LDR274==:020000		;LINE IS A 2741
LDRHLF==010000		;HALF DUPLEX LINE (TWX OR DC10C)
LDRRMT==:004000		;REMOTE NON-DATASET LINE
XP LDRDSR,LDRDSD+LDRRMT	;REMOTE OR DATA SET LINE (FOR PATCH)
			; SO CAN'T ATTACH TO PROJECT 1 #
;*** END OF GROUP FOR LDPVR2 ***
LDRREM==:002000		;TERMINAL AT REMOTE STATION
LDRSHC==:001000		;SUPPRESS HUNG CHECK -I.E. DON'T FORCE CHAR'S OUT
			;  WHEN NO XMIT FLAG.--SET BY 680 FOR SPECIAL
			;  DEVICES (E.G. 2741) & ITS OPR. TERMINAL

IFN FTCIMP,<		;[arpa]
 XP LDRIMP,000400	;[arpa] TTY IS AN ITY (IMP TTY)
			;[arpa] STOLEN BIT - DEC RESERVES 9 BITS FOR LINE NUMBER,
			;[arpa] BUT WE ONLY USE 8, AND THIS BIT MUST BE IN THE
			;[arpa] SAME HALF WORD AS LDRPTY.
XP LDRPTI,LDRPTY!LDRIMP	;[arpa] LINE IS A  PTY OR IMP TTY
> ;END IFN FTCIMP	;[arpa]

;BITS TO BE CLEARED ON A 400 RESTART
ZZR==LDRPTY+LDRCTY+LDRSHC+LDROSU

;DEFINITIONS OF BITS FOR GETLIN UUO, CLOSELY ASSOCIATED WITH ABOVE

GTLRDY==100		;BIT FOR GETLIN TO INDICATE WAITING BREAK CHAR
GTLT37==20		;MODEL 37 BIT (COPY OF LDLLCT)
GTLT35==10		;MODEL 35 BIT (COPY OF LDLTAB)
GTLLCP==4		;LOCAL COPY (OLD FULTWX) (COPY OF LDLLCP)
GTLXON==2		;XON IS TRUE (COPY OF L2RXON)
GTLMSK==LDR274!777	;BITS TO CLEAR ON GETLIN
LGLSET==GTLT37+GTLT35+GTLLCP+GTLXON	;MAY BE SET BY SETLIN


;BITS THAT ARE TESTED ON A CALL TO XMTCHR TO SEPARATE OUT
;THE NORMAL CASE FROM THE SPECIAL CASES.

DCHSPC==LDLIDL+LDLSTP+LDLSSO+LDLPIM+LDLFCP+LDLMIC,,LDRHLF

;MORE OF THE PROTOTYPE LINE DATA BLOCK ;⊗ LDBOFL LDBBYT L1LOFL L1RDEM L1RDEC L1RDEL L1RCHP L1RMIF LDIBCM

LDBOFL::!
LDBBYT::!0		;A WORD OF BYTES FOR THIS LINE

;BITS	POINTER	USE
;35-28	LDPECK	ECHO CHECK FOR HALF DUPLEX LINES
;27	L1RDEM	DEFERRED ECHO BIT.  SET BY SET TERMINAL DEFER
;26	L1RDEC	ECHO MAY ECHO 1 CHARACTER IF DEFERRED
;25	L1RDEL	ECHO MAY ECHO 1 LINE IF DEFERRED
;24-22	LDPCPU	CPU NUMBER--
;21	L1RCHP	CHANGE HARDWARE PARAMETERS FLAG (MEANINGUL EVEN FOR PTYS!)
;20	L1RMIF	MIC INTERLOCK FLAG
;19-15	LDPTIM	TIMEOUT ON IMAGE INPUT
;14-06	LDPSVC	SAVE CHARACTER DURING FREE CRLF, ↑X, ETC.
;05-03	POHPOS	OLD HORIZONTAL POSITION. NEEDED FOR TAB SIMULATION
;02-01	LDPFLC	COUNT OF NUMBER OF FILLERS BY CLASS
;0		1 IF FRONT END FOR THIS LINE IS DOWN.
;		 USE LDBOFL AS THE SYMBOL TO SKIPGE/SKIPL ON.
L1LOFL==:400000		;THE OFF-LINE BIT
L1RDEM==:1B27		;DEFERRED ECHO MODE
L1RDEC==:1B26		;MAY ECHO ONE CHARACTER (DEFERRED ECHO ONLY)
L1RDEL==:1B25		;MAY ECHO ONE LINE (DEFERRED ECHO ONLY)
L1RCHP==:1B21		;CHANGE HDW PARMS
L1RMIF==:1B20		;MIC INTERLOCK FLAG
LDIBCM==477777,,600000+L1RDEM+L1RDEC+L1RDEL+L1RCHP+L1RMIF+377 ;MASK TO CLEAR LDBBYT AT TTYINI. ALL ARE CLEARED
			; EXCEPT LDPFLC

;ANOTHER BYTE WORD, FLAGS AT LEFT. ;⊗ LDBBY2 L2LDEL L2LCCS L2LHD1 L2LHD2 L2LHD3 L2LHD4 L2LHD5 L2LSND L2LTAP L2LHDM L2LCLR L2RXON L2RECS
LDBBY2::!0
;BITS	POINTER	USE
;35-28	LDPRCS	MOST RECENT RECEIVED CHARACTER
;20-27	LDPWID	WIDTH OF TERMINAL CARRIAGE
;18-19	BITS - SEE BELOW
;9-17	LDPDSC	DATASET CONTROL TABLE INDEX BACK POINTER
;0-8	BITS - SEE BELOW

L2LDEL==:400000		;LAST CHAR IN WAS A DELETE
L2LCCS==200000		;LAST CHAR IN WAS A ↑C
L2LHD1==100000		;XMT DONE FLAG SEEN THIS CHAR ON HDX LINE
L2LHD2==040000		;RCV DONE FLAG SEEN THIS CHAR ON HDX LINE
L2LHD3==020000		;IGNORING RCV INTS DUE TO ECHO CHECK ERR ON HDX LINE
L2LHD4==010000		;NEXT RCV INT WILL BE CUE AFTER ECHO CHK
L2LHD5==004000		;RECEIVE ECHO WAS IN FACT NOT SAME AS XMT CHAR
L2LSND==:002000		;SEND ALLOWED WHILE BUSY
L2LTAP==:001000		;↑Q FROM KEYBOARD TURNS ON L2RXON. SET BY .TERMINAL TAPE COMMAND

L2LHDM==L2LHD1!L2LHD2!L2LHD3!L2LHD4!L2LHD5

L2LCLR==L2LDEL!L2LCCS!L2LHDM!L2LSND!L2LTAP
			;CLEARED ON INITIALIZATION

L2RXON==:400000		;XON IS TRUE (PAPER TAPE INPUT)
L2RECS==200000		;EAT COMMAND SYNC, FOR TTCALL 10
IFN FTCIMP,<			;[arpa] ;⊗ LDBIMP LDBQUO

;[arpa] IMP DEVICE INFORMATION

LDBIMP::0		;[arpa] IF NON-ZERO, POINTER TO IMP DDB ADDR FOR CROSSPATCH


LDBQUO::0		;[arpa] QUOTE/ESCAPE CHARS AND DATA

;[arpa] (byte pointers and bits are defined and mostly used in TCPSER)
;[arpa] BITS	POINTER	USE

;[arpa] 29-35	LDPQUO	QUOTE CHARACTER(INITIAL VALUE ↑N)
;[arpa] 22-28	LDPSFT	CASE SHIFT CHARACTER (NO INITIAL VALUE)
;[arpa] 15-21	LDPLCL	LOCAL TELNET ESCAPE (INITIAL VALUE ↑← OR ↑?)
;[arpa] 08-14	LDPNET	NETWORK ESCAPE CHARACTER (NO INITIAL VALUE)
;[arpa] 00-03	  INDICATOR BITS:
;[arpa]	03		LQLNet	network escape typed
;[arpa]	02		LQLDwn	shift mode (0=up, 1=down)
;[arpa]	01		LQLSft	previous character was shift char.
;[arpa]	00		LQLQuo	previous character was quote char (sign bit)

> ;[arpa] END FTCIMP
IFN FTLINK,<			;[link] ;⊗ LDBLNK LDBLKB

;[link] TERMINAL LINK INFORMATION

;[link] BITS ARE DEFINED IN S.MAC FOR EASE OF USE BY BOTH SCNSER AND LNKSER

EXTERN	LNKSER		;[link] FORCE LINK LOADER TO INCLUDE LINK CODE

LDBLNK::0		;[link]

;[link] BITS	NAME	POINTER	USE

;[link] 0	LNKXMT		TTY IS ABOUT TO TRANSMIT BECAUSE OF LINK
;[link] 1	LNKACV		TTY HAS ACTIVE LINKS
;[link] 2	LNKREF		TTY IS REFUSING FURTHER LINKS
;[link] 3-11		LNKPTR	HEAD OF LINKED LIST OF LINKED TTY'S (LNKTBL IN COMMON)
;[link] 12	LNKECH		SENDING ECHO CHAR TO LINKED TTY
;[link] 13	LNKFLP		SEND INPUT FILLS TO LINKED TTY (LDBFLP)
;[link] 14	LNKOPD		ON CLOCK TICK, START OUTPUT TO THIS TTY IF NOT ACTIVE

LDBLKB::0	;[link] HEAD/TAIL OF LINKED LIST OF ECHO CHARACTERS IN
		;[link] INTERMEDIATE BUFFER. SEE LNKGET/LNKPUT IN LNKSER.

;[link] LOCATIONS EXTERNAL TO LNKSER:

INTERN	LDPSVC,FLLFLG,RCHLT1,LDBFLP
INTERN	LDBDCH,LDLIDL,LDBTOP,LDBTOT,TYOVRG
> ;[link] END FTLINK
;PAGE COUNTER WORD AND PAGE FLAGS ;⊗ LDBPAG LPLIRM LPLPAG LPLXOF LPLALT LPLBLK LPLSLF LPLSAP LPLDIS LPLPOK LPLACR LPLCLR
LDBPAG::!0
;BITS	POINTER USE
;30-35	LDPPCT	PAGE COUNTER
;24-29	LDPPSZ	PAGE SIZE
;18-23	LDPPFF	#LF'S REMAINING ON F.F. SIMULATION
;10-17	LDPACR	AUTO CRLF COUNTER
;8		WE ARE FORCING XMIT START VIA TOPOKE
;7	LDPDIS	TERMINAL IS A DISPLAY TERMINAL (HANDLES <DEL>'S)
;6		SEND ALL PENDING
;5		DON'T OUTPUT ANY MORE SINGLE L.F.'S
;4		SUPPRESS BLANK LINES (SET TERMINAL NO BLANK)
;3	LDPALT	ALTMODE CONVERSION (SET TERMINAL ALT)
;2		AN XOFF WAS SENT, XON NEEDED SOMETIME
;1		SET TERMINAL PAGE HAS BEEN DONE
;0		TERMINAL HAS NOT BEEN HEARD FROM IN THIS SECOND

LPLIRM==400000		;LOST TRANSMIT INTERRUPT BIT
LPLPAG==:200000		;SET TERMINAL PAGE COMMAND WAS EXECUTED
LPLXOF==100000		;SENT XOFF, ALWAYS SEND AN XON LATER
LPLALT==:40000		;ALTMODE CONV. (1:CONVERT 175,176 TO 033)
LPLBLK==:20000		;SUPPRESS BLANK LINES
LPLSLF==10000		;SUPPRESS LINE FEEDS
LPLSAP==:4000		;SEND ALL PENDING
LPLDIS==:2000		;SET IF THIS IS A DISPLAY TERMINAL
			; I.E., BACKSPACE MOVES CURSOR BACKWARDS
			; SPACE "ERASES" CHARACTER ON SCREEN
			; TERMINAL HAS ABILITY TO "HOME UP" CURSOR
LPLPOK==1000		;WE ARE FORCING XMIT START VIA TOPOKE (PREVENT RACE)
LPLACR==377		;AUTO CRLF COUNTER
LPLCLR==LPLIRM!LPLXOF!LPLBLK!LPLSLF!LPLSAP!LPLACR  ;CLEARED BY LDBINI
;FLAGS AND POINTER TO INTERUPT SERVICE ROUTINES ;⊗ LDBISR LILCFE LILRSP LILTSP LILAPL LILDBK LILRTC LILTDY ISRTYP ISRDSC ISRCHK ISRINI ISRCHP ISRLPC ISRELE ISRREM ISROFL
LDBISR::!BLOCK	1	
;BITS	POINTER	USE
;0	N/A	1 IF THE FRONT END IS CLEVER, 0 IF DUMB
;1-4	LDPTSP	TRANSMIT SPEED
;5-8	LDPRSP	RECEIVE SPEED
;9	LDPAPL	APL MODE
;10	LDPDBK	DEBREAK FEATURE EXISTS
;11	LDPRTC	CONTROL-R, CONTROL-T COMPATIBILITY
;12	LDPTDY	USER SAID "SET TERMINAL TIDY"
;13-17	CONTAIN T1 FOR @LDBISR(U)
;18-35	ADDRESS OF ISR DISPATCH TABLE

LILCFE==:(1B0)		;CLEVER FRONT END
LILRSP==:(17B4)		;RECEIVE SPEED
LILTSP==:(17B8)		;TRANSMIT SPEED
LILAPL==:(1B9)		;APL MODE
LILDBK==:(1B10)		;LINE HAS DEBREAK
LILRTC==:(1B11)		;CONTROL-R, CONTROL-T ARE PASSED TO PGM
LILTDY==:(1B12)		;DO NOT EXPAND OUTPUT

;FUNCTIONS ARE
ISRTYP==:0		;OUTPUT DATA IN T3 ON LINE POINTED TO BY U
ISRDSC==1		;DATA SET CONTROL
ISRCHK==:2		;TEST FOR LOST PIA
ISRINI==:3		;INIT ISR
ISRCHP==:4		;CHANGE HARDWARE PARAMETERS
ISRLPC==:5		;SEND LINE PARAMETER CONTROL MSG
ISRELE==:6		;SET ELEMENT #
ISRREM==:7		;DO REMOTE TERMINAL STUFF
ISROFL==:10		;SKIP IF FRONT END ON LINE
;⊗ LDBQUE LDBTTW LDLFSP LDLUAR LDLUAW LDLNAN LDBBCD
;LDBQUE -- QUEUED PROTOCOL WORD

LDBQUE::BLOCK	1

;BITS
;0-17		QUEUE HEADER
;18-36		NEXT LINE IN QUEUE

;TERMINAL TYPE WORD

LDBTTW::BLOCK	1
;0-7	LDPLCH	LAST CHAR READ BY COMCON.
;8		FREE
;9	LDLFSP	FULL SCNSER PTY
;10	LDLUAR	ON IF PROCESSING CONTROL R
;11	LDLUAW	ON IF PROCESSING CONTROL W
;12	LDLNAN	ON IF AN ALPHA-NUMERIC WAS SEEN WHILE PROCESSING CONTROL W
;		STOP ON SPACE OR TAB
;13-20	LDPFCT	FILLER REPEAT COUNTER
;21-28	PRPOS	POSITION OF PROMPT
;29-35	LDPTTT	TERMINAL TYPE AS SPECIFIED BY TTY TYPE COMMAND

LDLFSP==:400	;FULL SCNSER PTY
LDLUAR==200	;CONTROL R IN PROGRESS
LDLUAW==100	;CONTROL W IN PROGRESS
LDLNAN==40	;ON IF AN ALPHA-NUMERIC CHARACTER HAS BEEN SEEN


IFN FTD10H,<
;FLAGS FOR 2741 SUPPORT
LDBBCD::BLOCK	1
>
;FIVE WORDS FOR REMOTE STATION TERMINAL STATUS ;⊗ LDBREM LDBCCH LDBVTQ LRLVTM LRLCON LRLSTS LRLSCH LRLDST LRLQED LRLDIP LRLTTO LRLTTW LRLSCG LRLEPW LRLIMO LRLADR LRLXOF LRLCHR LRLDTR LRLDSR LRLDSL LRLATO LRLADL LRL741 LRLTIW LRRSHC LRLCLR LDBTTD LTLXOF LTLRBS LTLCTO LTLAXF LTLACK

IFN FTNET,<			;NETWORK RELATED LDB FIELDS

LDBREM::BLOCK	5		;WORDS REQUIRED FOR REMOTE TERMINALS

;			LAYOUT OF LDBREM FIELDS
;
; +0	BYTE (19)BITS-USED-BY-NETTTY, (1)0, (16)LAST-DAP-STATUS-MESSAGE-SENT
; +1	BYTE (36)LAST-CHARACTERISTICS-MESSAGE-SENT
; +2	BYTE (14)SLA, (14)DLA, (8)REMOTE-LINE-NUMBER
; +3	BYTE (4)2741-ELEMENT-NUMBER, (8)DRQ-COUNT, (8)EPM-SERIAL, (16)NODE-#
; +4MCR	BYTE (9)NEXT-CHAR-TO-OUTPUT, (9)DISCONNECT-TIMER, (9)JOB, (9)UNUSED
; +4VTM	BYTE (16)DELAYED-STATUS-MESSAGE, (2)0, (18)VTM-QUEUE-LINK


;DEFINE SYMBOLS FOR SOME LDBREM ENTRIES
LDBCCH==:LDBREM+1		;COMPRESSED CHARACTERISTICS WORD
LDBVTQ==:LDBREM+4		;NETVTM'S QUEUE LINK HALF-WORD

;			BITS USED IN LDBREM

;BITS USED BY BOTH NETVTM(LOCAL SET HOST) AND NETMCR(REMOTE TERMINALS)

LRLVTM==:(1B0)			;*** MUST BE SIGN BIT ***
				;  IF SET, THEN THIS IS A "LOCAL TERMINAL"
				;  THAT HAS "SET HOSTED" TO ANOTHER HOST.
LRLCON==:(1B1)			;IF SET, THEN TERMINAL IS "CONNECTED"
				;  (I.E. NCL CONNECT SEQUENCE IS COMPLETE)
LRLSTS==:(1B2)			;IF SET, THEN A "STATUS" MESSAGE IS REQUIRED
				;  SAME BIT, BUT DIFFERENT MSGS FOR VTM & MCR

;BITS USED ONLY BY NETVTM (LOCAL "SET HOST")

LRLSCH==:(1B3)			;IF SET, THEN A "CHARACTERISTICS" MESSAGE
				;  IS REQUIRED (WORKS LIKE "LRLSTS")
LRLDST==:(1B4)			;A "DELAYED" STATUS MESSAGE IS REQUIRED
				;  (USED TO OPTIMIZE MESSAGE TRAFFIC.
				;  THIS BIT HAS PRIORITY OVER LRLSTS)
LRLQED==:(1B5)			;IF SET, THEN VTM LINE HAS BEEN "QUEUED"
				;  BY "VTMENQ"
LRLDIP==:(1B6)			;IF SET, THEN WE HAVE/WANT-TO INITIATE A 
				; DISCONNECT ON THIS LINE
;BITS USED ONLY BY NETMCR ("NORMAL" REMOTE TERMINALS .. ALA DN87)

LRLTTO==:(1B3)			;LDPCHR HAS THE NEXT CHAR TO OUTPUT. THIS IS
				; NECESSARY SINCE THERE IS NO WAY TO TELL IF
				; XMTCHR WILL GIVE A CHAR WITH OUT GETTING IT.
LRLTTW==:(1B4)			;LINE IS WAITING FOR A DATA-REQUEST
LRLSCG==:(1B5)			;↑O ACTION REQUESTED (SEND CHAR GOBBLER)
LRLEPW==:(1B6)			;ECHO PIPELINE MARKER WAITING TO GO.
LRLIMO==:(1B7)			;INDICATES THAT REMOTE IS IN IMAGE MODE OUTPUT
LRLADR==:(1B8)			;USE OF THE AUTO-DIALER HAS BEEN REQUESTED
LRLXOF==:(1B9)			;AN XOFF (↑S) MESSAGE HAS BEEN REQUESTED
LRLCHR==:(1B10)			;THIS TERMINAL HAS RECEIVED AT LEAST 1
				; CHARACTERISTICS MSG.  (SEE NETTTY.MAC, ROUTINE
				; SCNMCR FOR DETAILS OF THE RACES INVOLVED...)
LRLDTR==:(1B11)			;RING/CARRIER BIT (SET/CLEARED BY STATUS MSGS
				; FROM THE -11)
LRLDSR==:(1B12)			;THE -10'S COPY OF WHAT IT THINKS LRLDTR
				; SHOULD BE.  (KEPT SO WE CAN TELL IF THE -11
				; CHANGED IT WHILE WE WEREN'T LOOKING)
LRLDSL==:(1B13)			;THIS LINE IS A DATA-SET LINE
LRLATO==:(1B14)			;INDICATES THAT THIS LINE POSSESSES THE AUTO-
				; BAUD CAPABILITY.  (SET/CLEARED BY THE ATTRIB
				; FIELD OF THE CONNECT MESSAGE)
LRLADL==:(1B15)			;INDICATES THAT THIS LINE POSSESES AN AUTO-
				; DIALER (ALSO SET BY CONNECT MESSAGE)
LRL741==:(1B16)			;INDICATES THAT THIS IS A 2741 LINE.
LRLTIW==:(1B17)			;SAYS THAT WE ARE IN TTY INPUT WAIT.  (I.E. WE
				; SHOULD UNLOCK THE 2741'S KEYBOARD)
LRRSHC==:1B18			;SAYS THAT THE LINE AT THE OTHER END HAS
				;  "SET HOST CAPABILITY".  (I.E. IT CAN
				;  RESPOND TO DISCONNECT MESSAGES).  NOT
				;  SET FOR DC72 LINES. SET FOR ALL OTHERS.

LRLCLR==:LRLDSR!LRLDTR!LRLTIW	;BITS THAT ARE OFF ON "VIRGIN" LINES
>;END OF IFN FTNET


;DEFINITIONS FOR SUPPORT OF RSX-20F TERMINALS

IFN FTKL10,<		;TTD'S ONLY ON A KL
LDBTTD::!0		;LINE INFO FOR -20F LINES
;	740000		;REMEMBERED TRANSMIT SPEED
;	036000		;REMEMBERED RECEIVE SPEED
LTLXOF==:1000		;SENT XOFF TO -20F
LTLRBS==:400		;REMOTE BIT SENT FOR -20F DATASETS
LTLCTO==:200		;NEED TO SEND FLUSH OUTPUT TO -20F
LTLAXF==:100		;AUTO-XOFF ENABLE SENT TO -20F
LTLACK==:40		;LINE WAITING FOR AN ACK
>;END FTKL10
IFN FTMIC,<		;IF MIC INCLUDED ;⊗ LDBMIC LDLCHK LDLMCC LDLOPC LDLERC LDLMCP LDLMCB LDLSIL LDLMMM LDLMTI LDLCL1 LDLMCA LDLRSP LDLRSY LDLLOG LDBLOT LDBLOC LDBLEN
;WORD FOR MIC TO USE
LDBMIC::0

;0	SET IF SOME BIT 1-14 IS SET
;1	SET IF A ↑C HAS BEEN TYPED
;2	SET IF OPERATOR CHAR SEEN IN COLUMN1
;3	SET IF ERROR CHAR SEEN IN COLUMN 1
;4	SET IF A ↑P HAS BEEN TYPED
;5	SET IF A ↑B HAS BEEN TYPED
;6	SILENCE THIS LINE
;7	LINE IN MONITOR MODE
;		NOT SET IN LDBMIC BUT IS SET ON A MICGET
;8	LINE IN USER MODE AND IN TI WAIT OR IN MONITOR MODE
;	AND CAN ACCEPT A COMMAND
;		NOT SET IN LDBMIC BUT IS SET ON A MICGET
;9	LINE IS IN COLUMN 1 ON OUTPUT
;	USED FOR ERROR AND OPERATOR CHECKING
;10	SET IF A ↑A HAS BEEN TYPED (ABORT)
;11	SET IF TERMINAL OUTPUT IS AVAILABLE
;15-21	ASCII CHAR TO BE TREATED AS OPERATOR CHAR
;		SET IN RESPONSE TO OPERATOR COMMAND
;		CLEARED IN RESPONSE TO NOOPERATOR COMMAND
;		OR ON LOGOUT
;22-28	ASCII CHAR TO BE TREATED AS ERROR CHAR
;		SET IN RESPONSE TO ERROR COMMAND
;		CLEARED IN RESPONSE TO NOERROR COMMAND
;		OR ON LOGOUT
;29-35	MIC MASTER JOB NUMBER - ENABLES MORE THAN ONE MIC TO RUN

LDLCHK==400000		;SOMETHING EXCITING HAPPENED
LDLMCC==200000		;↑C TYPED
LDLOPC==100000		;OPERATOR CHARACTER SEEN IN COLUMN 1
LDLERC==40000		;ERROR CHARACTER SEEN IN COLUMN 1
LDLMCP==20000		;↑P TYPED
LDLMCB==:10000		;↑B TYPED
LDLSIL==4000		;THIS LINE IS .SILENCE'D
LDLMMM==2000		;LINE IN MONITOR MODE (MICGET)
LDLMTI==1000		;LINE IN INPUT READY STATE
LDLCL1==400		;CARRIAGE IS IN COLUMN 1
LDLMCA==200		;↑A TYPED
LDLRSP==100		;ERROR RESPONSE
LDLRSY==:40		;RESPONSE CODE SYNC
IFN FTMLOG,<
LDLLOG==20		;MIC IS LOGGING

LDBLOT::0		;LOG TAKER,,COUNT OF CHARS TO LOG
LDBLOC::0		;COUNT OF CHARACTERS TO LOG
> ;END OF FTMLOG CONDITIONAL
> ;END OF MIC CONDITIONAL
DEPHASE

LDBLEN==:.-SCNLDB		;SIZE OF DATA BLOCK FOR A LINE
;DISPATCH TABLE FOR PTYS AND CTYS. ;⊗ CTYDSP ERRDSP LS0000 LS0050 LS0075 LS0110 LS0134 LS0150 LS0200 LS0300 LS0600 LS1200 LS1800 LS2400 LS4800 LS9600

IFN FTKI10!FTKS10,<
CTYDSP::JRST	CTYTYO		;TYPEOUT
	POPJ	P,0		;MODEM CONTROL
	POPJ	P,0		;ONCE A SECOND
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;CHANGE HARDWARE PARMS
	POPJ	P,		;LINE PARM CONTROL
	POPJ	P,		;SET ELEMENT
	POPJ	P,		;REMOTE STUFF
	JRST	CPOPJ1##	;IS LINE UP?
>

ERRDSP::POPJ	P,0		;TYPEOUT
	POPJ	P,0		;MODEM CONTROL
	POPJ	P,0		;ONCE A SECOND
	POPJ	P,0		;INITIALIZATION
	POPJ	P,0		;CHANGE HARDWARE PARMS
	POPJ	P,		;LINE PARM CONTROL
	POPJ	P,		;SET ELEMENT
	POPJ	P,		;REMOTE STUFF
	JRST	CPOPJ1##	;IS LINE UP?

;LINE SPEED MNEMONICS

LS0000==:0	;ZERO BAUD
LS0050==:1	;50 BAUD
LS0075==:2	;75 BAUD
LS0110==:3	;110 BAUD
LS0134==:4	;134.5 BAUD
LS0150==:5	;150 BAUD
LS0200==:6	;200 BAUD
LS0300==:7	;300 BAUD
LS0600==:10	;600 BAUD
LS1200==:11	;1200 BAUD
LS1800==:12	;1800 BAUD
LS2400==:13	;2400 BAUD
LS4800==:14	;4800 BAUD
LS9600==:15	;9600 BAUD

;DATA POINTERS INTO LDB ;⊗ LDPLCH LDPFCT LDPTTT LDPCPU LDPFLC LDPLNO LDPLNO LDPSVC LDPTIM LDPECK LDPDEM LDPFRM LDPTAB LDPLCT LDPIMI LDPPIM LDPFCS LDPBKA LDPALT LDPDIS LDPOSU PRPOS POHPOS LNPVRG LDPVR1 LDPVR2 LDPCMX LDPRCS LDPWID LDPDSC

LDPLCH:	POINT	8,LDBTTW(U),7		;POINTER TO LAST CHAR COMCON READ
LDPFCT:	POINT	8,LDBTTW(U),20		;POINTER TO FILLER REPEAT COUNTER
LDPTTT::POINT	7,LDBTTW(U),35
LDPCPU::POINT	3,LDBBYT(U),24
LDPFLC::POINT	2,LDBBYT(U),2		;POINTER TO INDEX OF FILLER CLASSES

IFN FTCIMP,<				;[arpa]
LDPLNO::POINT	8,LDBDCH(U),35		;[arpa] POINTER TO HARDWARE LINE NUMBER
>					;[arpa]  RESPECTS STOLEN BIT FOR LDRIMP
IFE FTCIMP,<				;[arpa]
LDPLNO::POINT	9,LDBDCH(U),35		;POINTER TO HARDWARE LINE NUMBER
>					;[arpa]

LDPSVC:	POINT	9,LDBBYT(U),14		;POINTER TO SAVED CHARACTER
					;TO BE USED AFTER FILLERS SENT
LDPTIM:	POINT	5,LDBBYT(U),19		;POINTER TO FIELD WHICH TIMES OUT
					; IMAGE MODE INPUT
IFN FTHDPX!FTTRACK,<
LDPECK::POINT	8,LDBBYT(U),35		;POINTER TO LAST CHARACTER SENT, FOR
					; ECHO CHECK ON HDX LINE
>
LDPDEM::POINT	1,LDBBYT(U),↑L<L1RDEM>	;POINTER TO L1RDEM BIT
LDPFRM:	POINT	1,LDBDCH(U),↑L<(LDLFRM)>;POINTER TO HARDWARE FORM FEED BIT
LDPTAB:	POINT	1,LDBDCH(U),↑L<(LDLTAB)>;POINTER TO HARDWARE TABS BIT
LDPLCT:	POINT	1,LDBDCH(U),↑L<(LDLLCT)>;POINTER TO LOWER CASE BIT
LDPIMI::POINT	1,LDBDCH(U),↑L<(LDLIMI)>;POINTER TO IMAGE MODE FLAG
LDPPIM::POINT	1,LDBDCH(U),↑L<(LDLPIM)>;POINTER TO PIM MODE FLAG
LDPFCS::POINT	1,LDBDCH(U),↑L<(LDLFCS)>;POINTER TO FULL CHAR SET FLAG
LDPBKA::POINT	1,LDBDCH(U),↑L<(LDLBKA)>;POINTER TO BREAK ON ALL CHARS FLAG
LDPALT:	POINT	1,LDBPAG(U),↑L<(LPLALT)>;POINTER TO ALTMODE CONVERSION BIT
LDPDIS:	POINT	1,LDBPAG(U),↑L<(LPLDIS)>;POINTER TO DISPLAY TERMINAL BIT
LDPOSU:	POINT	1,LDBDCH(U),↑L<LDROSU>	;POINTER TO OUTPUT SUPPRESSION (↑O) BIT
PRPOS:	POINT	8,LDBTTW(U),28		;POINTER TO HORIZONTAL POSITION AFTER PROMPT
POHPOS:	POINT	3,LDBBYT(U),5		;POINTER TO LOW 3 BITS OF HPOS
					; BEFORE A TAB (FOR TAB SIMULATION)
LNPVRG:	POINT	13,LINTAB##(T1),12	;POINTER TO LOW CORE COPY OF BITS FOR RESTART
LDPVR1:	POINT	6,LDBDCH(U),17		;POINTER TO STORE SOME OF ABOVE BITS
LDPVR2:	POINT	5,LDBDCH(U),24		;POINTER TO STORE SOME MORE OF ABOVE.
LDPCMX::POINT	4,LDBDDB(U),12		;POINTER TO INDEX OF FORCED COMMANDS
IFN FTTRACK,<
LDPRCS:	POINT	8,LDBBY2(U),35		;POINTER TO RECEIVED CHARACTER
					; SAVED FOR WATCHING IN LIGHTS.
>
LDPWID::POINT	8,LDBBY2(U),27		;POINTER TO WIDTH OF TERMINAL CARRIAGE
IFN FTMODM,<
LDPDSC::POINT	9,LDBBY2(U),17		;POINTER TO DATASET CONTROL TABLE INDEX
>
LDPPSZ::POINT	6,LDBPAG(U),29		;PAGE SIZE (# OF LINES) ;⊗ LDPPSZ LDPPCT LDPPFF LDPDEB LDPSPD LDPRTC LDPRSP LDPTSP LDPAPL LDPDBK LDP274 LDPTDY LDPACR LDPSTS LDPSLA LDPDLA LDPRLN LDPELE LDPDRQ LDPEPM LDPRNN LDPRNF LDPCHR LDPADT LDPJOB LDPDST LDP.OP LDP.ER LDPMJN LDIDCM
LDPPCT:	POINT	6,LDBPAG(U),35		;PAGE COUNTER
LDPPFF:	POINT	6,LDBPAG(U),23		;L.F. COUNTER FOR SIMULATION OF V.T. & F.F.
LDPDEB::POINT	2,LDBBYT(U),26		;POINTER TO DEFERRED ECHO BITS
IFN <FTCAFE!FTKS10!FTNET>,<
LDPSPD::POINT	8,LDBISR(U),8		;BOTH SPEEDS
>
LDPRTC::POINT	1,LDBISR(U),11		;↑R, ↑T COMPATIBILITY
LDPRSP::POINT	4,LDBISR(U),8		;RECEIVE SPEED
LDPTSP::POINT	4,LDBISR(U),4		;TRANSMIT SPEED
LDPAPL::POINT	1,LDBISR(U),9		;APL MODE BIT
LDPDBK::POINT	1,LDBISR(U),10		;DEBREAK FEATURE EXISTS
LDP274::POINT	1,LDBDCH(U),22		;LINE IS A 2741
LDPTDY::POINT	1,LDBISR(U),12		;DO NOT EXPAND OUTPUT
LDPACR::POINT	8,LDBPAG(U),17		;AUTO CRLF POINT


IFN FTNET,<
;FIELDS IN THE LDBREM AREA.  (USED BY NETWORK LINES)

LDPSTS::POINT	16,LDBREM+0(U),35	;CONTAINS THE LAST DAP STATUS MESSAGE
LDPSLA::POINT	13,LDBREM+2(U),12	;CONTAINS OUR SOURCE LINK ADDRESS
LDPDLA::POINT	13,LDBREM+2(U),25	;CONTAINS OUR DESTINATION LINK ADDRESS
LDPRLN::POINT	10,LDBREM+2(U),35	;LINE NUMBER AT REMOTE STATION
LDPELE::POINT	4,LDBREM+3(U),3		;2741 ELEMENT NUMBER
LDPDRQ::POINT	8,LDBREM+3(U),11	;NUMBER OF DATA-REQUESTS FROM REMOTE
LDPEPM::POINT	8,LDBREM+3(U),19	;SERIAL NUMBER OF LAST EPM FROM REMOTE
LDPRNN::POINT	16,LDBREM+3(U),35	;NUMBER OF NODE OWNING THIS TTY
LDPRNF::POINT	16,LDBREM+3(F),35	; SAME AS ABOVE, EXCEPT INDEXED BY "F"

LDPCHR::POINT	9,LDBREM+4(U),8		;IF LRLTTO =1, THIS CONTAINS THE NEXT
					; OUTPUT CHARACTER
LDPADT::POINT	9,LDBREM+4(U),17	;AUTO-DISCONNECT TIMER.
LDPJOB::POINT	9,LDBREM+4(U),26	;POINTER TO JOB (ONLY FOR CONNECTS)
LDPDST::POINT	18,LDBVTQ(U),17		;"DELAYED" STATUS FOR VTM
>;END OF IFN FTNET
IFN FTMIC,<
LDP.OP:	POINT	7,LDBMIC(U),21		;OPERATOR CHARACTER
LDP.ER:	POINT	7,LDBMIC(U),28		;ERROR CHARACTER
LDPMJN:	POINT	7,LDBMIC(U),35		;MIC MASTER JOB NUMBER
> ;END IFN FTMIC



;BITS TO BE CLEARED ON A 140 RESTART

LDIDCM:	XWD	ZZL,ZZR			;TO CLEAR BITS IN LDBDCH
	SUBTTL	DATA STRUCTURES -- TTY DEVICE DATA BLOCK (DDB) ;⊗ TTYLST SCNDDB DDBLDB BYTCNT FRCEND IOLBKA CTLSUP IOSBKA IOSTEC IOSNEC IOSFCS

;PROTOTYPE SCANNER DDB. REPLICATED BY ONCE. ONE FOR EACH JOB.

	$LOW
TTYLST::			;LABEL FOR FIRST TTY DDB IN CHAIN

SCNDDB::			;GLOBAL LABEL
PHASE 0

	SIXBIT	/TTY0/		;DEVNAM (PHYSICAL NAME)
	XWD	0,STTYBF+1	;DEVCHR. SIZE OF USER BUFFER
	0			;DEVIOS
	XWD	0,SCNDSP	;DEVSER
	XWD	DVTTY+DVIN+DVOUT,<<1←A>+<1←AL>+<1←PIMMOD>+<1←I>>	;DEVMOD
	0			;DEVLOG (LOGICAL NAME)
	0			;DEVBUF
	0			;DEVIAD
	0			;DEVOAD
	0			;DEVSTS
	XWD	.TYTTY,0	;DEVSTA
	0			;DEVXTR
	0			;DEVEVM
	0			;DEVPSI
	0			;DEVESE
	0			;DEVHCW
	707000,,0		;DEVCPU
	0			;DEVJOB
DDBLDB::!0			;LH=FREE
				;RH=DDBLDB LINKS TO THE LDB.
DEPHASE
XP SCNDDS,.-SCNDDB
	$HIGH
BYTCNT:	POINT	12,DEVOAD(F),12

;DATA WITHIN THE DDB

;USE OF DEVIOS

;LEFT HALF
XP TTYOUW,400000	;REMEMBERS THAT IF IN IOW, IT IS FOR OUTPUT, AS
			; OPPOSED TO INPUT. I.E., WHICH INT WAKES JOB
FRCEND==:200000		;IN IMAGE INPUT, FORCE END OF FILE DUE TO TIMING
IOLBKA==100000		;TEMP INTERNAL BIT TO PRESERVE BKA OVER ↑C/CONT

;RIGHT HALF
IFN FTCIMP,<		;[arpa]
CTLSUP==4000		;[arpa] SUPPRESS ECHO OF CTRL CHAR
>			;[arpa]
IOSBKA==1000		;BREAK ON ALL CHARACTERS
IOSTEC==400		;SUPPRESS ECHO OF DOLLAR SIGN ON ALTMOD
IOSNEC==:200		;USER (E.G. LOGIN) SUPPRESSING ECHO
IOSFCS==100		;USER WANTS ALL CHARACTERS.
	SUBTTL	TRANSMIT INTERRUPT ROUTINE ;⊗ XMTINT XMTIN1

;ENTRY FROM DEVICE-DEPENDENT INTERRUPT SERVICE ROUTINE ON A
; TRANSMIT-DONE INTERRUPT. THE HARDWARE LINE NUMBER IS
; IN AC U.  ENTER AT XMTIN1 IF U IS SETUP TO THE LDB ADDRESS.


XMTINT::MOVE	U,LINTAB##(U)	;GET LINE DATA BLOCK ADDRESS
XMTIN1::MOVSI	T1,L1LOFL
	ANDCAM	T1,LDBOFL(U)
	SKIPGE	LDBDCH(U)	;ARE WE EXPECTING THIS?
	JRST	XMTDMC		;NO, GO UNLOCK KEYBOARD
	PUSHJ	P,XMTCHR	;GET A CHARACTER FROM THE CHUNKS
	  POPJ	P,		;END OF STRING
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	;CLEAR SINCE JUST SENT A CHARACTER
IFN FTHDPX,<
	MOVSI	T1,L2LHDM	;HALF DUPLEX BITS
	ANDCAM	T1,LDBBY2(U)	;CLEAR THEM IN THE LDB
>
	MOVEI	T1,ISRTYP	;FUNCTION DESIRED FROM DEVICE DRIVER
	PJRST	@LDBISR(U)	;GO DO IT

;XMTCHR -- ROUTINE TO RETURN THE NEXT CHARACTER TO SEND FROM ;⊗ XMTHCH XMTCHR XMTCH1 XMTCH2 XMTCH3 XMTCH4
;	   A TERMINAL OUTPUT BUFFER
;
;CALL
;	MOVE	U,LDB ADDRESS
;	PUSHJ	P,XMTCHR
;	  <IDLE CONDITION>
;	<CHARACTER IN T3>

XMTHCH:	MOVE	T1,LDBDCH(U)	;GET SPECIAL BITS FROM LDB
	TRZ	T1,LDRHLF	;BUT CLEAR HALF DUPLEX BIT FOR NOW
	JRST	XMTCH1		;JOIN XMTCHR

XMTCHR::MOVE	T1,LDBDCH(U)	;GET SPECIAL BITS FROM LDB
XMTCH1:	TDNE	T1,[DCHSPC]	;ANY UNUSUAL STATES?
	JRST	XMTSPC		;YES, GO HANDLE SPECIAL CASES
XMTCH2:	SCNOFF			;NO INTERRUPTS WHILE TAKING CHARACTERS
	SOSGE	T4,LDBTOC(U)	;COUNT DOWN LENGTH OF OUTPUT STREAM
	JRST	ZAPBUF		;IF EMPTY STREAM.  GO RESET COUNT
	LDCHKR	T3,LDBTOT(U)	;TAKE NEXT CHARACTER FROM STREAM
XMTCH3:	SCNON			;HAVE CHARACTER, ALLOW OTHERS TO ACCESS
	CAIN	T4,↑D50		;HAVE WE REACHED THE WAKE THRESHOLD?
	PUSHJ	P,XMTWAK	;YES, GO WAKE JOB IF WAITING
IFN	FTMIC,<
	MOVE	T4,LDBMIC(U)	;GET MIC BITS
	TLNE	T4,LDLSIL	;LINE SILENCED
	JRST	XMTCHR		;YES, EAT THE CHARACTER
>
XMTCH4:	TRNE	T3,400		;IS THIS AN IMAGE MODE CHARACTER?
	JRST	XMTCN6		;YES, COUNT IT AND RETURN
	ANDI	T3,177		;CLEAR POSSIBLE PARITY BIT
	SKIPGE	T1,CHTABL(T3)	;GET SPECIAL BITS, TEST FOR UNUSUAL CHAR
	JRST	XMTSPO		;THIS MAY REQUIRE FILL OR BLANK SUPPRESS
	AOSG	LDBHPS(U)	;INCREMENT HORIZONTAL POSITION
	JRST	XMTCN5		;RETURN IF NOT END OF CARRIAGE
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  JRST	XMTCN5		;NO FREE CRLF FOR LOG FILES
	MOVE	T2,LDBDCH(U)	;GET CHARACTERISTICS WORD
	TLNE	T2,LDLNFC	;USER WANT FREE <CR><LF>?
	JRST	XMTCN5		;NO, JUST SEND THE CHARACTER
	TLZ	T1,CHALT!CHUAE!CHCRE  ;OUTPUT CHARACTERS GO STRAIGHT
	PUSHJ	P,SETCRF	;YES, GO SETUP A CRLF FILLER
	  JRST	XMTFIL		; AND SEND THE FILLER INSTEAD
	JRST	XMTCN5		;GO SEND THE CHARACTER AFTER ALL!
;COUNT UP THE CHARACTERS PHYSICALLY OUTPUT AND RETURN ;⊗ XMTCNT XMTCN4 XMTCN5 XMTCN6 XMTCNX XMTSPO

XMTCNT:
IFN FTTVP,<
	CAIN	T3,12		;LINEFEED?
	PUSHJ	P,INCPCT	;DUMP PAGE COUNTER
>
XMTCN4:
IFN FTCIMP,<			;[arpa]
	SKIPE	LDBIMP(U)	;[arpa] IF AN IMP, DON'T TRASH IMAGE BIT YET
	  JRST	XMTCN6		;[arpa] JUST CHECK FOR TELNET CONTROL
>				;[arpa]
	ANDI	T3,777		;WE MAY HAVE TRASHED PARITY, SO
	LDB	T1,[POINT 7,T3,35] ;GET THE LOW ORDER 7 BITS
	MOVE	T1,CHTABL(T1)	;GET THE CHAR'S BITS
	TRNE	T3,400		;IS THIS IMAGE MODE FILL?
	  JRST	XMTCN6		;YES, DON'T MESS WITH PARITY
XMTCN5:	ANDI	T3,177		;CLEAR POSSIBLE BAD PARITY
	TLNN	T1,CHEPAR	;IF THE CHAR REQUIRES PARITY
	TRO	T3,200		;THEN MAKE THE PARITY EVEN
XMTCN6:
IFN FTCIMP,<			;[arpa]
	TRNE	T3,400		;[arpa] IMAGE BIT SET?
	 SKIPN	LDBIMP(U)	;[arpa] AND XPATCHED?
	  JRST	XMTCNX		;[arpa] NO, LEAVE IMAGE ALONE
	ANDI	T3,377		;[arpa] GET 8 BITS OF CHAR
	TRNE	T3,200		;[arpa] TELNET CONTROL?
	  JRST	XMTCHR		;[arpa] YES, NO ECHO
XMTCNX:				;[arpa]
>				;[arpa]
IFN FTRSP!FTACCT,<		;IF COUNTING CHARACTERS, THEN
	AOS	LDBOCT(U)	;COUNT CHARACTERS OUTPUT THIS LINE
	AOS	%SCNXI		;AND TOTAL CHARACTERS OUTPUT BY SYSTEM
> ;END IFN FTRSP!FTACCT
	PJRST	CPOPJ1##	;RETURN THE CHARACTER



;HERE FOR UNUSUAL CHARACTER ON OUTPUT

XMTSPO:	HLL	U,LDBDCH(U)	;SETUP LEFT HALF OF U WITH BITS
	TLNN	T1,CHEPAR	;NEED A PARITY BIT?
	TRO	T3,200		;YES, ADD IT
IFN FTTBLK,<
	MOVSI	T2,LPLBLK
	TDNE	T2,LDBPAG(U)
	PUSHJ	P,BLSUPO	;CHECK FOR TERMINAL NO BLANKS
>
	PUSHJ	P,ADJHP
	PUSHJ	P,SETFLO	;SETUP FILLERS IF ANY NEEDED
	  JRST	XMTFIL		;FILLS NEEDED, GO SEND THEM FIRST
IFN FTTVP,<
	CAIN	T3,12		;IF LINE FEED
	PUSHJ	P,INCPCT	; INCREMENT PAGE COUNT
>
	JRST	XMTCN6		;NONE NEEDED, JUST RETURN IT
;HERE WHEN A SPECIAL CONDITION BIT IS SET IN THE LDB.  THESE BITS ;⊗ XMTSPC XMTSP1 XMTSTP XMTSSO XMTFLC XMTCIS
;ARE PLACED IN LDBDCH IN SUCH A WAY THAT A JFFO INSTRUCTION CAN
;BE USED TO FIND THE CONDITION THAT NEEDS ATTENTION FIRST.

XMTSPC:	HLL	U,LDBDCH(U)	;CARRY LEFT HALF OF LDBDCH IN U 
	AND	T1,[LDLIDL!LDLSTP!LDLSSO!LDLFCP!LDLPIM!LDLMIC,,0]
	JFFO	T1,XMTSP1	;GET FIRST FLAG SET
	MOVE	T1,LDBDCH(U)	;REFRESH BITS
	JRST	XMTHDX

XMTSP1:	JRST	@[EXP XMTCIS,XMTSTP,XMTSSO,XMTFLC,XMTPIM,XMTMIC](T2)

XMTSTP:
XMTSSO:	SKIPN	LDBFLP(U)	;KROCK - ALLOW FILLER POINTER TO FINISH
	JRST	XMTIDL		;NO FILLER, NO OUTPUT
				;FALL INTO XMTFLC

XMTFLC:	SCNOFF			;NO INTERRUPTS WHILE TRY TO CLEAR FPC
	SKIPE	LDBXNP(U)	;XON CLASS POINTER?
	JRST	XMTXOF		;YES, GO SEND NOW
	SKIPE	LDBFLP(U)	;FILLER POINTER SETUP?
	JRST	[SCNON
		 JRST	XMTFI0]	;YES, GO SEND FILLER
	MOVSI	T1,LDLFCP	;SET TO CLEAR
	ANDCAM	T1,LDBDCH(U)	;FORCED CHARACTER PENDING
	SCNON
	JRST	XMTCHR		;NOW SEE WHAT NEEDS TO BE DONE

;HERE IF LINE IS IDLE.  CLEAR IDLE STATE AND TRY TO RETURN
; A CHARACTER.  XMTIDL WILL RESET IDLE IF NOTHING TO SEND.

XMTCIS:	MOVSI	T1,LDLIDL
	ANDCAM	T1,LDBDCH(U)	;MARK LINE AS BUSY
	PJRST	XMTCHR		;TRY TO RETURN A CHARACTER
;FALL THROUGH TO HERE TO IDLE A LINE. ;⊗ XMTIDL XMTPSI XMTDMC XMTWAK XMTWK1

XMTIDL:	HLL	U,LDBDCH(U)
	MOVSI	T1,LDLIDL	;LINE IS IDLE BIT
	IORM	T1,LDBDCH(U)	; SET IN LDB
	MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	; CLEAR
IFN FTCIMP,<			;[arpa]
	MOVEI	T1,LDRIMP	;[arpa] IMPISH?
	TDNE	T1,LDBDCH(U)	;[arpa] ....
	  PUSHJ	P,XMTQIT##	;[arpa] FINISH UP OUTPUT IMP MESSAGE
>				;[arpa]
IFN FTHDPX,<
	MOVSI	T1,L2LHDM	;CLEAR HALF DUPLEX FLAGS TOO
	ANDCAM	T1,LDBBY2(U)	; ..
>
	HRRZ	F,LDBDDB(U)	;ADDRESS OF LINKED DDB
	PUSH	P,J		;SAVE J
	JUMPE	F,XMTPSI	;JUMP IF NO DDB
	LDB	J,PJOBN##	;GET JOB NUMBER
	MOVE	T1,JBTSTS##(J)	;GET JOB STATUS
	TRNE	T1,JS.NTO	;HIBERING FOR NON-BLOCKING TTY OUTPUT?
	PUSHJ	P,WAKEJB##	;YES--WAKE HIM UP
XMTPSI:	POP	P,J		;RESTORE J

XMTDMC:	HRRZ	F,LDBDDB(U)	;IF NO DDB ALL DONE
	JUMPE	F,CPOPJ##	;IF NO DDB.
	MOVE	S,DEVIOS(F)	;IO STATUS
IFN FTCAFE&FT2741!FTNET,<
	SKIPGE	LDBDDB(U)	;ANY COMMAND?
	JRST	XMTWAK		;YES--WAIT FOR IT
	TLNE	U,LDLCOM	;AT COMMAND LEVEL?
	PUSHJ	P,UNLKBD	;YES--UNLOCK KEYBOARD
	JUMPGE	S,XMTWAK	;IF WAITING FOR OUTPUT
	TLNE	S,IOW		;WAITING FOR IO?
	PUSHJ	P,UNLKBD	;YES, THEREFORE INPUT MUST
				; UNLOCK 2741 KEYBOARD
>
XMTWAK:
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE
	PJRST	VTMENQ##	;  QUEUE THE LINE SO WE SEND MORE DATA-REQUESTS
>
IFN FTMIC,<
	SKIPN	T1,LDBMIC(U)	;CONTROLLED BY MIC?
	JRST	XMTWK1		;IF NOT
IFN FTMLOG,<
	TLNE	T1,LDLLOG	;LOGGING
	PUSHJ	P,MLOGOF	;TIDY UP
> ;END IFN FTMLOG
	PUSHJ	P,MICWAK	;WAKE MIC
> ;END IFN FTMIC
XMTWK1:
IFN FTCIMP,<			;[arpa]
	SKIPE	F,LDBIMP(U)	;[arpa] CROSSPATCHED IMP?
	  PUSHJ	P,RQTIIO##	;[arpa] YES - REQUEST IMP/TTY PROCESSING
>				;[arpa]
	HRRZ	F,LDBDDB(U)
	JUMPE	F,CPOPJ##
	MOVE	S,DEVIOS(F)
	TLNE	S,IOW		;IO WAIT?
	JUMPL	S,TTWAKE	;IF OUTPUT, GO WAKE JOB
	POPJ	P,		;IF INPUT, RETURN
;PACKED IMAGE MODE (PIM) TRANSMIT INTERRUPT. ;⊗ XMTPIM ZAPOU1 SONPJ1 SONPPJ

XMTPIM:	SCNOFF
	SOSGE	T4,LDBTOC(U)	;COUNT DOWN
	PJRST	ZAPOU1		;IF EXHAUSTED
	LDCHKR	T3,LDBTOT(U)	;TAKE A CHARACTER, RETURN STALE CHUNKS
	SCNON			;ALLOW INTERRUPTS
	CAIN	T4,↑D50		;IF LESS THAN 50. CHARS LEFT 
	PUSHJ	P,XMTWAK	;WAKE UP THE ATTATCHED JOB
	JRST	XMTCN6		;COUNT AND RETURN THE CHARACTER

;HERE WHEN THE OUTPUT STREAM COUNT IS EXHAUSTED.  RESET IT TO ZERO
;AND SET THE LINE IDLE.  COME HERE ONLY WITH SCANNER INTERLOCK SET.

ZAPOU1:	SETZM	LDBTOC(U)	;COUNT IS PROBABLY NEGATIVE NOW
	MOVE	T2,LDBTOT(U)	;$MAKE SURE PUTTER MATCHES TAKER
	CAME	T2,LDBTOP(U)	;$MAKE SURE BOTH POINTERS MATCH
	PUSHJ	P,RCCSTP	;$NO, DIE NOW
	SCNON			;ALLOW INTERRUPTS AGAIN
	PJRST	XMTIDL		;IDLE THE LINE


;ROUTINE TO ALLOW SCANNER INTERRUPTS AGAIN AND SKIP RETURN

SONPJ1::AOS	0(P)		;SKIP RETURN

SONPPJ::SCNON			;ALLOW SCANNER INTERRUPTS
	POPJ	P,		;AND RETURN
;HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBMIC IS NON-ZERO ;⊗ XMTMIC MICLG3

XMTMIC:
IFN FTMIC,<			;IF MIC
IFN FTMLOG,<
	MOVE	T2,LDBMIC(U)
	TLNE	T2,LDLLOG	;HAS HE ASKED FOR LOG
	SKIPE	LDBLOT(U)	;HAS HE GOT A LOG TAKER
	JRST	MICLG3
	MOVE	T2,LDBTOT(U)	;MAKE COPY OF TAKER
	MOVEM	T2,LDBLOT(U)
MICLG3:
> ;END OF FTMLOG CONDITIONAL
	PUSHJ	P,HPOS		;GET HORZONTAL POSITION ON LINE
	JUMPN	T2,XMTOK	;IN COLUMN 1?
	SKIPE	T2,LDBMIC(U)	;IS HE RUNNING MIC OR
	TLNN	T2,LDLRSP!LDLRSY	;WANTS RESPONSE FEATURE
	JRST	XMTOK1		;NO - MUST NOT INTERFERE
	TLNE	T2,LDLERC	;HAS HE HAD ERROR?
	TLNE	T2,LDLMCC	;AND NOT ↑C
	JRST	XMTOK1		;NO - IGNORE
	SKIPN	LDBTOC(U)	;IS THERE A CHARACTER WAITING?
	JRST	XMTOK1		;NO, IGNORE
	MOVE	T4,LDBTOT(U)	;COPY OF OUTPUT TAKER
	LDCHK	T3,T4		;PREVIEW NEXT CHARACTER
	LDB	T2,LDP.ER	;GET ERROR CHAR
	JUMPE	T2,XMTOK	;MUST BE ONE
	ANDI	T3,177		;JUST 7 BITS
	CAIE	T3,"?"		;IS IT A "?"
	CAMN	T3,T2		; OR THE ERROR CHARACTER
	CAIA			;YES, HANDLE MIC'S RESPONSE
	JRST	XMTOK		;NO IGNORE
	MOVSI	T2,LDLRSY!LDLCHK	;SET THE SYNC
	IORB	T2,LDBMIC(U)
	TLNN	T2,LDLRSP	;BEEN THIS WAY BEFORE
	JRST	XMTECH		;YES JUST DO ECHOING
	HRRZ	F,LDBDDB(U)
	JUMPE	F,XMTECH	;NO ATTACHED DDB
	MOVE	S,DEVIOS(F)
	TLNN	S,IOW		;IN IO WAIT?
	JRST	XMTECH		;NO FORGET IT
	MOVSI	T2,LDLRSP
	ANDCAM	T2,LDBMIC(U)	;SAY SYNC
	PUSHJ	P,MICWAK
	JRST	XMTECH		;AND PUT THE PLUG IN

XMTOK:	MOVE	T2,LDBMIC(U)	;GET MIC BITS ;⊗ XMTOK XMTOK1 ZAPBUF
XMTOK1:	TLNE	T2,LDLRSY	;WAITING FOR MIC TO TAKE RESPONCE
	JRST	XMTECH		;YES, KEEP THE PLUG IN

IFN FTMLOG,<
	SKIPN	LDBLOT(U)	;ARE WE LOGGING THIS?
	JRST	XMTCH2		;NO, GO TAKE CHARACTER NORMALLY
	SCNOFF			;NO INTERRUPTS
	SOSGE	LDBTOC(U)	;DECREMENT COUNT OF CHARACTERS AND TEST
	JRST	ZAPBUF		;IF OUTPUT STREAM NOW EMPTY
	LDCHK	T3,LDBTOT(U)	;TAKE A CHARACTER OUT OF THE STREAM
	AOS	LDBLOC(U)	;COUNT UP THE NUMBER TO BE LOGGED
	JRST	XMTCH3		; AND JOIN PROCESSING
> ;END IFN FTMLOG
> ;END OF IF MIC

;ENTER HERE WITH SCNOFF TO CLEAR LDBTOC AND CHECK FOR ECHO

ZAPBUF:	SETZM	LDBTOC(U)	;ZERO COUNT
	MOVE	T1,LDBTOP(U)	;GET PUTTER
	CAME	T1,LDBTOT(U)	;MUST MATCH TAKER
	PUSHJ	P,RCCSTP	; OOPS, SOMETHING IS WRONG
	SCNON			;ALLOW INTERRUPTS
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS A VTM LINE,
	PUSHJ	P,VTMENQ##	;  WE MUST BE SURE TO SEND DATA-REQUESTS
>				;  NOW THAT WE'RE OUT OF DATA.
	JRST	XMTECH		;LOOK FOR SOMETHING TO ECHO
;HERE ON A TRANSMIT DONE INTERRUPT WHEN LDBXNP IS NON-ZERO. ;⊗ XMTXOF XMTFIL XMTFI0
;LDBXNP IS A NINE-BIT BYTE POINTER TO FORCED CHARACTERS SUCH AS
; XOFF AND BELL.

XMTXOF:	SCNON			;ALLOW INTERRUPTS
	ILDB	T3,LDBXNP(U)	;GET A CHARACTER.
	JUMPN	T3,XMTCNT	;COUNT THE CHARACTER AND RETURN
	SETZM	LDBXNP(U)	;REACHED END. CLEAR POINTER
	SKIPN	LDBFLP(U)	;IS THERE A FILLER POINTER?
	JRST	XMTCHR		;NO, SEE IF ANY OUTPUT STREAM
				;YES, FALL INTO XMTFIL

;HERE ON A TRANSMIT-DONE INTERRUPT WHEN LDBFLP IS NON-ZERO.
;LDBFLP IS A NINE-BIT BYTE POINTER TO FILLER CHARACTERS, OR
; TO FREE CRLF'S OR TAB SIMULATIONS.

XMTFIL:
XMTFI0:	SCNOFF			;NO INTERUPTS FOR A FEW INSTRUCTIONS
	HLL	U,LDBDCH(U)	;REFRESH LEFT HALF OF U
	ILDB	T3,LDBFLP(U)	;GET A FILLER CHARACTER
	JUMPN	T3,XMTFI1	;IF NOT AT END, SEND IT AND DISMISS
	LDB	T1,LDPFCT	;FILL REPEAT COUNTER
	JUMPE	T1,XMTFI3	;JUMP IF NO REPEAT COUNT
	LDB	T3,LDPSVC	;SAVED CHARACTER
	SCNON			;OK TO INTERUPT WITH CHARACTER IN T3
	MOVSI	T1,LDLUAW	;CONTROL W BIT
	TDNE	T1,LDBTTW(U)	;PROCESSING CONTROL W?
	JUMPN	T3,[MOVEI T2,1	;YES, JUMP IF HARD COPY TERMINAL
		    PUSHJ P,SETFLP ;STORE DUMMY FILLER POINTER
;		    SETZ T1,	;ZERO SAVED CHARACTER
		    JRST XMTFI4];ECHO CHARACTER AND RETURN
	ANDI	T3,177		;JUST 7 BITS
	TDNE	T1,LDBTTW(U)	;SKIP IF NOT CONTROL W
	SKIPA	T1,CHTABL+"W"-100 ;GET CONTROL W DISPATCH
	MOVE	T1,CHTABL(T3)	;GET CHARACTER DISPATCH
	PUSHJ	P,(T1)		;DISPATCH TO CHARACTER HANDLING ROUTINE
	JRST	XMTFI0		;CHECK FOR MORE FILL
XMTFI3:SCNON ;⊗ XMTFI3 XMTFI4 XMTFI2 XMTFI1
	MOVSI	T1,LPLSAP	;WAITING TO DO A
	TDNE	T1,LDBPAG(U)	;SEND ALL?
	JRST	[SOSGE	SNDCTR##	;COUNT DOWN SEND ALL COUNT
		SETZM	SNDCTR##	;BUT DON'T LET IT GO NEGATIVE!
		ANDCAM	T1,LDBPAG(U)	;YES -- CLEAR BIT
		MOVE	T1,SNDPTR##	;SET UP POINTER
		MOVEM	T1,LDBFLP(U)	;STORE IN LDB
		JRST	XMTFI0]		;TYPE THE STRING
	SETZB	T1,LDBFLP(U)	;END. CLEAR THE BYTE POINTER AND T1
	LDB	T3,LDPSVC	;SEE IF ANY SAVED CHARACTER
	JUMPE	T3,XMTCHR	;IF NOT, RETURN TO XMTCHR AND TRY AGAIN
XMTFI4:	TLNE	U,LDLSSO	;A PAGE BREAK PENDING?
	JRST	[MOVE T2,FLLDMP	;YES, GET DUMMY FILLER POINTER
		 PUSHJ P,SETFLP	;AND SET IT IN THE LDB
		 JRST XMTIDL]	;MARK THE LINE AS IDLE
	DPB	T1,LDPSVC	;CLEAR THE SAVED CHAR BYTE
	TRNE	T3,400		;IF TAB SIMULATION
	JRST	XMTFI2		; WHO KNOWS
	ANDI	T3,177		;JUST CHARACTER
	MOVE	T1,CHTABL(T3)	;CHARACTER DESCRIPTOR BITS
	TRO	T3,200		;SO IT WILL ECHO
	JRST	XMTEC4		;GO TYPE IT

XMTFI2:	MOVE	T1,LDBDCH(U)
	TDNN	T1,[LDLLCP+LDLNEC,,LDRHLF]
	SKIPE	LDBTOC(U)	;WAS THAT CHAR FOR INPUT OR OUTPUT?
	JRST	XMTCH4		;OUTPUT. GO SEND IT WITH FILLERS
	IORI	T3,200		;SET THE "NEED TO ECHO THIS CHAR" BIT
	JRST	XMTEC6		;AND GO ECHO THE POOR THING

XMTFI1:SCNON
	CAIE	T3,FLLFLG	;IS THIS A FLAG OR A CHARACTER?
	PJRST	XMTCNT		;COUNT CHARACTER AND RETURN IT
	PUSHJ	P,SETFLC	;GET CORRECT FILL CLASS
	MOVE	T3,FLLCRP(T2)	;GET RIGHT CRLF POINTER
	MOVEM	T3,LDBFLP(U)	;PLACE IN FILLER POINTER
	PUSHJ	P,SCNBOL	;MAKE SURE AT LOGICAL BOL
	JRST	XMTFI0		;AND GO TYPE FROM IT.
;HERE WHEN BUFFERED AND FILLER OUTPUT DONE, AND LDBECT IS NON-ZERO ;⊗ XMTECH XMTEIP XMTEC1 XMTEC2
;NEED TO ECHO A CHARACTER THAT HAS BEEN TYPED IN.

XMTECH:
IFN FTNET,<
	SKIPGE	LDBREM(U)	;IF THIS IS AN ACTIVE VTM LINE
	JRST	XMTIDL		;  DON'T TRY TO ECHO ANYTHING.
>				;  THE CHUNKS ARE HORRIBLY MESSED UP.
	HLL	U,LDBDCH(U)
	HRRZ	T1,LDBBYT(U)	;GET WORD CONTAINING DEFERRED ECHO BITS
ifn ftcimp,<			;[arpa]
	SKIPE	LDBIMP(U)	;[arpa] Always echo immediately if xpatched
	  JRST	XMTEIP		;[arpa]
>				;[arpa]
	TRNE	T1,L1RDEM	;DEFERRED ECHO MODE SELECTED?
	TRNE	T1,L1RDEL!L1RDEC; HAS AN INPUT REQUEST BEEN MADE YET?
	CAIA			;EITHER INPUT WAIT OR IMMEDIATE ECHO
	JRST	XMTIDL		;DEFERRED AND NOT REQUESTED YET
IFN FTCIMP,<			;[arpa]
XMTEIP:				;[arpa] here to avoid defering echo.
>				;[arpa]
	SCNOFF			;DISALLOW INTERRUPTS
	SOSGE	LDBECC(U)	;ANY LEFT TO ECHO?
	JRST	ZAPECH		;NO, FINISH UP
	LDCHK	T3,LDBECT(U)	;TAKE CHARACTER FROM INPUT, SAVE CHUNKS
	AOS	T2,LDBTIC(U)	;COUNT THE INPUT CHARACTERS
	SCNON			;ALLOW INTERRUPTS
IFN FTRSP!FTACCT,<AOS %SCNEI>	;COUNT CHARACTERS ECHOED
	MOVEI	T4,L1RDEC	;CHARACTER REQUEST BIT
	PUSHJ	P,SPCHEK	;SEE IF IT'S SPECIAL.
	  JRST XMTEC1		;IT'S NOT.
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] don't treat as break if crosspatched
>				;[arpa]
	TLNN	T1,CHBRK	;YES. IS IT A BREAK CHAR?
	JRST	XMTEC1		;NOT A BREAK
	MOVEI	T4,L1RDEC!L1RDEL;GET LINE REQUESTED BIT
	AOS	LDBBKC(U)	;COUNT LINES IN THE LDB
IFN FTRSP!FTACCT,<AOS LDBBCT(U)>;COUNT BREAK CHARACTERS INPUT
XMTEC1:	ANDCAM	T4,LDBBYT(U)	;CLEAR, SINCE WE ECHOED A CHARACTER
	PUSH	P,T1		;SAVE CHARACTER BITS
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] always break if xpatched to an imp.
>				;[arpa]
	TLNE	U,LDLBKA+LDLIMI	;BREAK ON ALL CHARACTERS?
	JRST	[PUSHJ	P,RCVWKQ	;YES, WAKE JOB
	JRST	XMTEC2]		;AVOID EXTRA WAKE IF BREAK TOO
	CAIG	T2,TTIBRK	;ARE THERE OVER 72. OF THEM?
	TLNE	T1,CHBRK	;OR IS IT A BREAK CHARACTER?
	PUSHJ	P,ECHBRK	;YES. WAKE THE JOB, IF ANY
XMTEC2:	POP	P,T1		;RESTORE CHARACTER BITS INTO T1

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ XMTEC3 XMTEC4 XMTEC5 XMTEC6 XMTNCP XMTEC8

XMTEC3:
IFN FTMIC,<
	SKIPE	T2,LDBMIC(U)	;MIC IN CONTROL OF THIS LINE?
	TLNN	T2,LDLSIL	;YES, IS IT .SILENCED?
	CAIA			;NOT .SILENCED OR NOT MIC
	JRST	XMTCHR		;.SILENCED, EAT THE CHAR
> ;END IFN FTMIC
	TRNN	T3,400		;IMAGE?
	TLNE	U,LDLNEC	;NON-ECHOING?
	JRST	XMTEC6		;YES, LEAVE ALONE
	MOVE	T2,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TDNN	T2,[XWD LDLLCP,LDRHLF]	;LOCAL COPY?
	JRST	XMTEC4		;NO, COUNT UP NORMAL CHARACTER
	MOVEI	T2,L2RXON	;PAPER TAPE?
	TDNE	T2,LDBBY2(U)	;...
	JRST	XMTEC6		;YES.  NO FILLERS, ELSE GARBLE.
XMTEC4:	TLNE	T1,CHSPO	;SPECIAL CHARACTER OF SOME FLAVOR?
	JRST	XMTEC5		;YES, MORE EXTENSIVE HANDLING REQUIRED
	AOSG	LDBHPS(U)	;NORMAL CHARACTER, ECHO ONE CHAR POSITION
	JRST	XMTEC6		;GO DO IT
	SOS	LDBHPS(U)	;UNDO AOSG (ADJHP WILL RE-DO IT)
XMTEC5:
IFN FTTBLK,<
	MOVSI	T2,LPLBLK	;THE SUPPRESS-BLANK-LINES BIT
	TDNE	T2,LDBPAG(U)	;"TTY NO BLANK" SET?
	PUSHJ	P,BLSUPI	;YES, NOTE PASSING <LF>S ET AL
> ;IFN FTTBLK
	PUSHJ	P,ADJHP		;ADJUST CARRIAGE POSITION FOR ECHOED CHARACTER
IFN FTCIMP,<			;[arpa]
	SKIPE	LDBIMP(U)	;[arpa] IF CROSSPATCHED...
	  ANDI	T3,377		;[arpa]  ...CLEAR IMAGE BIT FOR ECHOING.
>				;[arpa]
	PUSHJ	P,SETFLI	;SET FILLERS FOR ECHOING
IFN FTLINK,<			;[link]
	  JRST	[			;[link] needs filler
		 PUSHJ	P,CHKLKF##	;[link] SEND FILLER TO ANY LINKS
		 JRST	XMTFI0		;[link] AND OUTPUT FROM FILL POSITION
		]			;[link]
>
IFE FTLINK,<			;[link]
	  JRST XMTFI0		;OUTPUT FROM FILLER POSITION.
>				;[link]
XMTEC6:
ifn FTCIMP,<	;[arpa] check to see if we REALLY want to echo this
	skipn	ldbimp(u)	;[arpa] cross patched?
	  jrst	XMTNCP		;[arpa] no.  don't check
	move	t1,t3		;[arpa] copy character
	andi	t1,177		;[arpa] JUST the character
	move	t1,chtabl(t1)	;[arpa] get the bits for it.
	TLNE	T1,CHALT	;[arpa] IF ALT OR ↑X SUPPRESS ECHO 
	  jrst	XMTChr		;[arpa] go get next character
XMTNCP:				;[arpa] come here if not cross patched
> ;[arpa] end of ifn FTCIMP

IFN FTMIC,<
	SKIPE	T1,LDBMIC(U)	;RUNNING MIC?
	TLNE	T1,LDLMCB	;IN MIC BREAK?
	CAIA			;IN MIC BREAK, DO NORMAL ECHO CHECKING
	JRST	XMTEC8		;NO, MIC CHARACTERS ALWAYS ECHO
> ;END IFN FTMIC
	MOVE	T1,LDBDCH(U)	;GET LEFT AND RIGHT HALF BITS
	TDNE	T1,[XWD LDLLCP,LDRHLF!LDR2741]	;EITHER TYPE OF LOCAL COPY?
	JRST	XMTCHR		;YES. DO NOT ECHO THE CHARACTER
IFN FTNET,<
	TRNN	T3,600		;IF IMAGE, OR NOT ECHOED BY REMOTE
	JRST	XMTCHR		;IF NOT VTM, DON'T ECHO, IF VTM, MUST ECHO HERE
> ;END IFN FTNET		;ECHO THE CHARACTER NOW
XMTEC8:	TLNN	U,LDLCOM	;CHARACTER ITSELF SHOULD BE ECHOED
	TLNN	U,LDLNEC	;UNLESS USER LEVEL AND HE SAID NO
	JRST	XMTCN4		;RETURN CHARACTER
	JRST	XMTCHR		;NO, STEP TO NEXT CHARACTER
ZAPECH:	SETZM	LDBECC(U)	;FIX UP ;⊗ ZAPECH ECHBRK RCVWKQ XMTHDX XMTHDX SETCHP CLRIRM
	MOVE	T2,LDBTIP(U)	;$MESSED UP
	CAME	T2,LDBECT(U)	;$CHECK POINTERS
	PUSHJ	P,RCCSTP	;$SOMETHING IS WRONG
	SCNON			;ALLOW INTERRUPTS
	JRST	XMTIDL

ECHBRK:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  PJRST RCVWAK		;NO. WAKE JOB IF ANY.
	PJRST	COMSET		;YES. SET COMMAND REQUEST.

RCVWKQ:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  PJRST	RCVWAK		;NO. WAKE JOB.
	POPJ	P,0		;YES. DON'T MAKE COMMAND FOR LDLBKA

IFE FTHDPX,<
XMTHDX==CPOPJ##
>
IFN FTHDPX,<
XMTHDX:	JUMPL	T1,XMTHCH	;IF LINE IS IDLE, JUST TREAT NORMALLY
	MOVSI	T1,L2LHD1	;FLAG THAT XMT DONE HAPPENED
	IORB	T1,LDBBY2(U)	; ..
	TLNN	T1,L2LHD2	;HAS REC INT OCCURRED ALSO?
	POPJ	P,		;RETURN
	JRST	RHDERQ		;YES. GO SEE IF ERROR IN ECHO
>

;ROUTINE TO QUEUE FOR A CHANGE HARDWARE PARAMETER MESSAGE

SETCHP::MOVEI	T1,L1RCHP
	IORM	T1,LDBBYT(U)	;MARK THAT ISRCHP MUST BE CALLED
	PJRST	TOPOKE		;ADD TO QUEUE

CLRIRM::MOVSI	T1,LPLIRM	;IRMA BIT
	ANDCAM	T1,LDBPAG(U)	;CLEAR IN LDB
	POPJ	P,		;RETURN
TOREQ::	MOVSI	T1,LDLIDL ;⊗ TOREQ TOPOKE
	IORM	T1,LDBDCH(U)
;;	PJRST	TOPOKE

;ROUTINE TO PLACE AN LDB INTO THE START OUTPUT QUEUE.  SCANNED
;AT CLOCK LEVEL ONCE PER TICK.
;CALL
;	MOVEI	U,LDB ADDRESS
;	PUSHJ	P,TOPOKE
;	<RETURN HERE ALWAYS>
;USES T1,T2

TOPOKE::MOVEI	T1,LDRPTY	;PTY BIT
	TDNE	T1,LDBDCH(U)	;IS THIS A PTY?
	PJRST	PTYPE##		;YES, DON'T QUEUE OUTPUT
	MOVSI	T1,LPLPOK	;OUTPUT BEING STARTED BIT
	TDNE	T1,LDBPAG(U)	;CHECK BEFORE WE GET THE INTERLOCK
	POPJ	P,		;  JUST FOR EFFICIENCY'S SAKE
	SCNOFF			;NO INTERRUPTS
	TDNE	T1,LDBPAG(U)	;...
	JRST	SONPPJ		;YES, BY SOMEONE ELSE
	IORM	T1,LDBPAG(U)	;NO.  INDICATE LDB IS GOING INTO THE QUEUE
	HLRZ	T1,LDBQUE(U)	;GET THE QUEUE HEADER ADDRESS
	HLRZ	T2,0(T1)	;LAST ENTRY OF CURRENT QUEUE
	SKIPN	T2		;NON-NULL QUEUE?
	MOVEI	T2,-LDBQUE(T1)	;POINT TO QUEUE HEADER WORD
	HRRM	U,LDBQUE(T2)	;STORE ADDRESS OF ARGUMENT LDB AT END
	HRLM	U,0(T1)		;UPDATE LATEST ENTRY
	HLLZS	LDBQUE(U)	;MAKE SURE LIST TERMINATESS
	JRST	SONPPJ		;ALLOW INTERRUPTS AND RETURN


;ROUTINE TO TAKE AN LDB OUT OF THE 'START OUTPUT' QUEUE ;⊗ TOTAKE TOTAK1
;CALLED FROM DEVICE DRIVERS TO FIND LINES THAT ARE WAITING TO DO OUTPUT.
;CALL
;	MOVE	T1,ADDRESS OF LIST HEADER
;	PUSHJ	P,TOTAKE
;	  <IF EMPTY QUEUE>
;	<LDB ADDRESS IN U>
;
;USES T2.

TOTAKE::SKIPN	0(T1)		;IF QUEUE IS EMPTY NOW
	POPJ	P,		; AVOID INTERLOCK
	SCNOFF
TOTAK1:	MOVSI	T2,LPLPOK	;HAS OUTPUT BEEN STARTED?
	HRRZ	U,0(T1)		;POINT TO FIRST LDB IN LIST
	JUMPE	U,SONPPJ	;IF NONE
	ANDCAM	T2,LDBPAG(U)	;CLEAR 'IN QUEUE' BIT
	HRRZ	T2,LDBQUE(U)	;NEXT LDB IN LIST
	SKIPN	T2		;END OF LIST?
	SETZM	0(T1)		;YES, CLEAR HEADER
	HRRM	T2,0(T1)	;ADVANCE LIST
	SKIPGE	LDBDCH(U)	;IS OUTPUT ALREADY GOING?
	JRST	SONPJ1		;LINE IDLE, GIVE GOOD RETURN
	MOVEI	T2,L1RCHP
	TDNN	T2,LDBBYT(U)	;NEED TO SEND CHANGE PARAMETER MESSAGE?
	JRST	TOTAK1		;NO, SKIP TO NEXT
	JRST	SONPJ1		;YES, RETURN THE LINE
	SUBTTL	RECEIVE INTERRUPT ROUTINE ;⊗ RECINT RecImp RECPTY RECINU RECINN

;HERE FROM DEVICE-DEPENDENT INTERRUPT ROUTINE ON A RECEIVE INTERRUPT.
;AT THIS POINT, T3(28-35) HAS RECEIVED CHARACTER, U HAS PHYSICAL LINE #
;AS INDEX INTO LINTAB

RECINT::MOVE	U,LINTAB##(U)	;LOAD LDB ADDRESS
IFN FTCIMP,<			;[arpa]	
	SKIPE	LDBIMP(U)	;[arpa] IF XPATCHED...
	  ANDI	T3,377		;[arpa] ... USE ONLY 8 BITS OF CHARACTER

RecImp::	;[arpa] come here to handle stuff coming over the IMP
>;[arpa]
RECPTY:	MOVEI	T2,L1RMIF	;MIC INTERLOCK FLAG
	SCNOFF			;LOCK OTHER CPU
	TDNE	T2,LDBBYT(U)	;IS MIC TYPING ON THIS LINE?
	JRST	SONPPJ		;YES, IGNORE CHAR
	IORM	T2,LDBBYT(U)	;SET THE INTERLOCK BIT
	SCNON			;ALLOW INTERRUPTS
	PUSHJ	P,RECINU	;PROCESS THE INTERRUPT
	MOVEI	T2,L1RMIF	;GET THIS BIT AGAIN
	ANDCAM	T2,LDBBYT(U)	;CLEAR INTERLOCK
IFN FTRSP!FTACCT,<		;IF COUNTING CHARACTERS
	AOS	LDBICT(U)	;COUNT INPUT CHARACTERS THIS LINE
	AOS	%SCNRI		;AND INPUT CHARACTERS FOR THE SYSTEM
> ;END IFN FTRSP!FTACCT
	POPJ	P,		; AND DISMISS THE INTERRUPT

RECINU:
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] LEAVE IMAGE BIT ALONE IF XPATCHED
>				;[arpa]
	ANDI	T3,377		;JUST 8 BITS OF CHARACTER.
				; CLEAR ANY DEVICE DEPENDENT BITS
IFN FTNET,<			;IF NETWORK
	SKIPGE	LDBREM(U)	;IF THIS IS AN ACTIVE VTM LINE,
	JRST	VTMREC##	;  GO HANDLE NVT CHARS SPECIAL
>
	MOVSI	T1,L1LOFL	;PUT TERMINAL ON LINE
	ANDCAM	T1,LDBOFL(U)	;SINCE SOMEONE IS THERE
IFN FTMODM,<
	MOVE	T1,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TRNN	T1,LDRREM	;IS IT A NETWORK LINE?
	TRNN	T1,LDRDSD	;IS IT A DATASET LINE?
	  JRST	RECINN		;NO.  PROCESS CHARACTER
	LDB	T1,LDPDSC	;GET DATASET TABLE INDEX
	MOVE	T1,DSCTAB##(T1)	;GET DATASET DATA
	TLNE	T1,DSCBLI	;WANT TO IGNORE INTERRUPTS?
	  POPJ	P,		;YES,
RECINN:
> ;END OF IFN FTMODM
	MOVEI	T1,ST.NRT	;THE STAND ALONE (NO REMOTE) BIT
	TDNE	T1,STATES##	;IS THE SYSTEM STAND ALONE?
	JRST	[HRR	T1,LDBDCH(U)	;YES, GET CHARACTERISTICS
		TRNN	T1,LDRDSR	;IS THE TERMINAL REMOTE/DATASET?
		JRST	RECIN0		;NO, LOCAL, ALLOW IT
		HRRZ	T1,LDBDDB(U)	;REMOTE, BUT IS IT ALREADY IN USE?
		JUMPN	T1,RECIN0	;YES, ALLOW IT TO CONTINUE TO WORK
		JRST	BEATIT]		;NO, DUMP IT

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ RECIN0 RECIN1 RECNXI RECIN2 RECQRT RECI2A

RECIN0:
IFN FTTRACK,<DPB T3,LDPRCS>	;SAVE RECEIVED CHARACTER FOR DEBUG
IFN FTHDPX,<
	MOVE	T1,LDBDCH(U)	;SEE IF IT IS HALF DUPLEX
	TRNE	T1,LDRHLF	; ..
	JRST	RECHDX		;YES. SPECIAL HANDLING
> ;END IFN FTHDPX
RECIN1:	HLL	U,LDBDCH(U)	;CARRY DEVICE BITS IN LH.
	TLNE	U,LDLPIM	;PIM MODE?
	JRST	REPIM		;YES, GO TO PIM CODE
	SKIPG	TTFREN##	;ANY SPACE FOR CHARACTERS?
	JRST	RCHLT1		;NO. SHUT IT DOWN.
	TLNN	U,LDLIMI	;IN IMAGE INPUT MODE?
	JRST	RECIN2		;NO.
IFN FTCIMP,<			;[arpa]
RECNXI::			;[arpa] here to send stuff from NetQuo
>				;[arpa]
	MOVEI	T1,IMGTIM	;YES. RESET TIMEOUT FIELD TO MAX
	DPB	T1,LDPTIM	; ..
	TRO	T3,400		;MARK IN NINTH BIT.
	JRST	RECINA		;AND GO STORE IN BUFFER. NO BREAK.
RECIN2:	SKIPG	LDBTIC(U)	;FIRST INPUT CHARACTER ON LINE
	JRST	[PUSHJ	P,HPOS	;YES, GET CURRENT HORIZONTAL POSITION
		DPB	T2,PRPOS;REMEMBER IT FOR ERASING TABS
		JRST	.+1]
IFN FTCIMP,<			;[arpa]
	SKIPN	F,LDBIMP(U)	;[arpa] CROSSPATCHED TO IMP?
	  JRST	RECQRT		;[arpa] NO.
	TRNE	T3,400		;[arpa] YES - SPECIAL CHAR HANDLING?
	  JRST	RECINA		;[arpa] YES - STORE AS IS
	ANDI	T3,177		;[arpa] NO, STRIP PARITY
	pushj	p,RecQuo##	;[arpa] check for network quotes or whatever.
	  popj	p,		;[arpa] it was something and we sent it.
RECQRT:				;[arpa]
>				;[arpa]
	PUSHJ	P,SPCHEK	;SEE IF IT'S SPECIAL. SET T1 UP.
	  JRST RECIN3		;NON-SPECIAL. SEE IF LOWER CASE
IFN FTCIMP,<			;[arpa]
	TLNN	T1,CHXPIH	;[arpa] SPECIAL EVEN IF CROSSPATCHED?
	  JUMPN	F,RECI2A	;[arpa] JUMP IF CROSSPATCHED (F SET UP BEFORE)
>;[arpa]  END IFN FTCIMP
	TLNE	T1,CHRIA	;DOES THIS CHAR NEED SPECIAL RCV HANDLING?
	JRST	0(T1)		;YES. GO TO IT.
				;NO. FALL INTO ORDINARY CHAR HANDLER
IFN FTCIMP,<			;[arpa]
	JRST	RECINA		;[arpa] JUMP AROUND IMP CODE

RECI2A:	TLZ	T1,CHBRK!CHCNC	;[arpa] SUPPRESS SPECIAL HANDLING BECAUSE CROSSPATCHED
	IORI	T3,400		;[arpa] SET IMAGE BIT
> ;[arpa] END FTCIMP
;HERE WITH T1=CHARACTER BITS (LH=0 IF NONE), T3=CHARACTER ;⊗ RECINA RECINB RWARNX RECIN6 RECLN1

IFE FTWATCH,<RICT:>
RECINA:	TRNE	T3,400		;IF THIS IS AN IMAGE MODE CHAR,
	JRST	RECINB		; DON'T TOUCH THE ECHO/PARITY BIT
	TRO	T3,200		;FIRST, ASSUME THAT REMOTE DIDN'T ECHO CHAR
IFN FTNET,<
	MOVE	T2,LDBDCH(U)	;GET THE CHARACTERISTICS, AND
	TRNN	T2,LDRREM	;  IF THIS LINE IS A LOCAL LINE (NOT REMOTE)
	JRST	RECINB		;  THEN THE REMOTE DIDN'T ECHO THE CHAR.
	MOVEI	T2,STY.DE	;GET THE "REMOTE LOCAL ECHO" BIT
	TDNN	T2,LDBREM(U)	; AND IF THE REMOTE IS ECHOING THE CHARS,
	TRZ	T3,200		; THEN CLEAR THE "NEEDS ECHOING" BIT
>
RECINB:	MOVE	T2,LDBTIC(U)	;COUNT CHARACTERS LINE HAS INPUT
	ADD	T2,LDBECC(U)	;PLUS LEFT TO ECHO
	PUSH	P,T1		;SAVE CHARACTER BITS
	CAILE	T2,TTIWRN	;TIME TO WARN HIM?
	JRST	RWARN		;YES.  GO SEND XOFF.
RWARNX:	SCNOFF
	STCHK	T3,LDBTIP(U)	;STORE CHARACTER
	AOS	LDBECC(U)	;COUNT CHARACTER TO ECHO
	POP	P,T1		;RESTORE T1
IFN FTCIMP,<		;[arpa] XPATCHED TTYS DON'T HAVE BREAK CHARACTERS
	SKIPE	LDBIMP(U)		;[arpa] crosspatched?
	  JRST	[			;[arpa] no.  no more nonsense.
		 SCNON			;[arpa] interrupts back on
		 movsi	T2,L2LCCS!L2LDEL;[arpa] set to clear ↑C and <DEL> bits
		 JRST	RECINI		;[arpa] 
		]			;[arpa]
>					;[arpa]
	TLNE	T1,CHBRK	;BREAK CHARACTER?
	PUSHJ	P,SETBKU	;YES, NOTE PLACE
	SCNON
IFN FTMIC,<			;IF MIC
	SKIPE	LDBMIC(U)	;IS HE RUNNING MIC?
	PUSHJ	P,MICECH	;YES - SEE IF <CR> TYPED
> ;END OF IF MIC
	MOVE	S,FLLBSP	;PREPARE BACKSLASH POINTER
	MOVSI	T2,L2LDEL	;WAS PREVIOUS CHAR A RUBOUT?
	TDNN	T2,LDBBY2(U)	; ..
	JRST	RECIN6		;NO
	MOVEM	S,LDBFLP(U)	;YES. STORE BACKSLASH FILLER PTR
	MOVSI	S,LDLFCP	;FORCING FLAG
	IORM	S,LDBDCH(U)	;FLAG FOR XMTCHR
IFN FTLINK,<			;[link]
	PUSH	P,T1		;[link] PRESERVE AGAINST RAVAGES OF TIME
	PUSH	P,T2		;[link] DITTO
	PUSHJ	P,CHKLKF##	;[link] RAVAGES - CHECK FOR FILL LINKS
	POP	P,T2		;[link] UNPRESERVE
	POP	P,T1		;[link] OTTID
> ;[link] END IFN FTLINK
	AOS	LDBHPS(U)	; AND COUNT POSITION OF BACKSLASHES
RECIN6:	TLNN	T1,CHCNC	;IS THIS CHARACTER A CONTROL C?
	TLO	T2,L2LCCS	;NO. PREPARE TO CLEAR L2LCCS BIT
IFN FTCIMP,<RECINI:>		;[arpa] here if crosspatched.
	ANDCAM	T2,LDBBY2(U)	;CLEAR DELETE AND CONTROL C FLAGS
IFN FTLINK,<			;[link]
	TLNN	T1,CHUAE	;[link] ECHO AS ↑X?
	 TLNE	U,LDLNEC	;[link] OR NOT ECHOING AT ALL?
	  JRST	RECLN1		;[link] YES - DON'T ECHO TO LINKS EITHER
	MOVSI	T2,LNKECH	;[link] MARK AS SENDING ECHO TO LINKS
	IORM	T2,LDBLNK(U)	;[link] ....
	PUSH	P,T1		;[link] KEEP IT AROUND
	PUSHJ	P,CHKLNK##	;[link] SEND ECHO TO ANY OPEN LINKS
	POP	P,T1		;[link]
RECLN1:				;[link]
> ;[link] END FTLINK
	PJRST	TOPOKE		;QUE TO GET ECHO STARTED
RECIN3:	TLNN	U,LDLLCT	;DOES HE WANT UPPER? ;⊗ RECIN3 RECIN4 SETBKU
	JRST	RECIN4		;NOPE, DON'T BOTHER WITH ANYTHING ELSE
ifn FtCImp,<			;[arpa]
	LDB	T2,LDPSFT##	;[arpa] ANY SHIFT CHAR DEFINED?
	JUMPN	T2,RECIN4	;[arpa] YES - BYPASS
	SKIPE	LDBIMP(U)	;[arpa] CROSSPATCHED?
	  jrst	[		;[arpa] yes.  make sure upper case
		 trne	t3,100	;[arpa] character range?
		   trz	T3,40	;[arpa] yes.  make sure upper case.
		 jrst	RecIn4	;[arpa] and skip other checks
		]		;[arpa]
> ;[arpa] END FTCIMP
	LDB	T2,[POINT 7,T3,35]	;GET SEVEN BITS OF CHARACTER
	CAIL	T2,140		;IS IT LOWERCASE (AS DEF .GT. 140)?
	TRC	T3,240		;YES. MAKE UPPER, CORRECT PARITY
RECIN4:
IFN FTCIMP,<			;[arpa]
	SKIPE	LDBIMP(U)	;[arpa] DON'T DO AUTO CRLF IF XPATCHED
	  JRST	RECINA		;[arpa]
>				;[arpa]
	LDB	T4,LDPACR	;GET AUTO CRLF BYTE
	JUMPE	T4,RECINA	;IGNORE IF ZERO
	TLNN	U,LDLCOM
	TRNE	T3,137		;SEE IF SPACE
	JRST	RECINA		;NO--FORGET IT
	PUSHJ	P,HPOS		;GET POSITION ON LINE
	SUBI	T2,(T4)		;SEE IF ROOM
	JUMPL	T2,RECINA	;JUMP IF YES
	MOVEI	T3,215		;ELSE CONVERT TO
	JRST	RECIN2		;CR


;ROUTINE TO REMEMBER THE BREAK CHARACTER POSITION IN LDBBKU

SETBKU:	MOVE	T2,LDBTIP(U)	;LOCATION OF INPUT PUTTER
	MOVEM	T2,LDBBKU(U)	;SAVE IT
	POPJ	P,
IFN FTHDPX,< ;⊗ RECHDX RHDERQ RHDERR RHDER2 RHDER1 ECHOUT ECHO ECHOL

RECHDX:	JUMPGE	T1,RECIN1	;IF NOT OUTPUTTING, TREAT AS KEYBOARD FLAG
	MOVE	T1,LDBBY2(U)	;OUTPUTTING. CONSIDER ECHO.
	TLNE	T1,L2LHD3	;DURING IGNORE TIME?
	POPJ	P,0		;YES. IGNORE.
	MOVSI	T1,L2LHD2	;FLAG FOR RCV INT
	LDB	T2,LDPECK	;NO. GET CHAR LAST SENT OUT
	CAIE	T2,0(T3)	;IS IT CORRECT?
	TLO	T1,L2LHD5	;NO. PUT ERROR FLAG IN TOO
	IORB	T1,LDBBY2(U)	;SET RCV DONE AND ERROR IF ERROR OCCURRED
IFE FT630H,<
	TLNN	T1,L2LHD1	;HAS XMT FLAG HAPPENED TOO?
	POPJ	P,0		;NO. WAIT FOR IT.
>
RHDERQ:	TLNN	T1,L2LHD5	;ERROR ON RCV INT?
	JRST	XMTHCH		;NO, PROCESS AS TRANSMIT DONE
				;YES. FALL INTO ERROR ROUTINE
RHDERR:	MOVSI	T1,L2LHD4	;IS THIS AN ERROR OR THE RESPONSE TO IT?
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RHDER1		;ERROR.
	ANDCAM	T1,LDBBY2(U)	;RESPONSE. CLEAR RESP FLAG
	MOVE	T2,T3		;CONSIDER WITHOUT PARITY
	ANDI	T2,177		; ..
	CAIN	T2,"O"-100	;CONTROL O?
	JRST	RHDER2		;YES.
	CAIE	T2,"C"-100	;CONTROL C?
	JRST	XMTHCH		;NO, TREAT AS TRANSMIT DONE
	MOVSI	T1,L2LCCS	;YES. MAKE IT LOOK LIKE TWO OF THEM
	IORM	T1,LDBBY2(U)	; ..
RHDER2:	MOVSI	T1,LDLIDL
	IORM	T1,LDBDCH(U)
	MOVSI	T1,LPLIRM
	ANDCAM	T1,LDBPAG(U)
	JRST	RECIN1		;AND GO PROCESS AS RECEIVE INTERRUPT

RHDER1:	MOVSI	T1,L2LHD3+L2LHD4	;ERROR. FLAG FOR IGNORE RCV INTS
	IORM	T1,LDBBY2(U)	; ..
	AOS	T1,ECHCNT	;UPDATE COUNTER
	CAILE	T1,10		;TOO MANY CLOCK REQUESTS?
	JRST	ECHOUT		;YES
	MOVE	T1,TICSEC##	;DELAY FOR HALF SECOND
	LSH	T1,-1
	HRLI	T1,ECHO		;COME TO ECHO AFTER DELAY
	SYSPIF			;PUT REQUEST IN CLOCK QUEUE
	IDPB	T1,CLOCK##	; ..
	IDPB	U,CLOCK##
	SETOM	CLKNEW##
	JRST	ONPOPJ##	;ENABLE INTERRUPTS AND RETURN

ECHOUT:	SOS	ECHCNT		;SO COUNT STAYS RIGHT
	JRST	ONPOPJ##	;ONE LESS QUEUE ENTRY
ECHO:	MOVSI	J,MTTYLN##	;HERE AT CLK LEVEL. CLEAR TERMINAL IGNORE FLAGS
	MOVSI	T1,L2LHD3	;IN ALL TTY LDB'S
	SOS	ECHCNT		;ONE LESS QUEUE ENTRY
ECHOL:	HRRZ	U,LINTAB##(J)	;GET AN LDB ADDRESS
	ANDCAM	T1,LDBBY2(U)	;CLEAR IGNORE BIT
	AOBJN	J,ECHOL		;DO FOR ALL LINES
	POPJ	P,0		;RETURN TO CLOCK LEVEL
>
;HERE ON RECEIVE INTERRUPT OF A CONTROL-C CHARACTER ;⊗ RICA RICC RICC RICC2 RICC3 RICC1

IFN FTMIC,<			;IF MIC
RICA:	SKIPN	LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	RECINA		;NO NORMAL CONTROL CHAR
				;YES - FALL INTO RICC

RICC:	PUSH	P,T1		;SAVE CHARACTER BITS
	SKIPE	T1,LDBMIC(U)	;IS MIC RUNNING FOR US?
	PUSHJ	P,MICRIC	;YES - EXTRA GOODIES
> ;END OF IF MIC
IFE FTMIC,<			;IF NOT MIC
RICC:	PUSH	P,T1		;SAVE CHARACTER BITS
> ;END OF IF NOT MIC
	PUSH	P,T3		;RIDLN CLOBBERS T3
	PUSHJ	P,RIDLN		;DO THE CONTROL-U FUNCTION
	POP	P,T3		;RECOVER ↑C FOR ECHO
	HRRZ	F,LDBDDB(U)
	JUMPE	F,RICC2
	LDB	J,PJOBN##
	LDB	T1,LDPDEB	;DEFERRED ECHO BITS
	DPB	T1,JBYDEB##	;SAVE IN JOB TABLE
RICC2:	MOVSI	T1,L2LCCS	;SEE IF SECOND CONTROL C
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RICC1		;NO
IFN FTTPAG,<
	MOVSI	T1,LDLSTP+LDLSSO;YES - CLEAR STOP BIT
	ANDCAM	T1,LDBDCH(U)
>
	PUSHJ	P,CNCCHK	;YES. AM I ALLOWED TO BELIEVE THE CONTROL-C?
	  JRST RICC1		;SLAVE, OR NOT SECOND. JUST STORE
	PUSHJ	P,TTHALT	;JACCT AND TWO ↑C↑C
	HRRZ	F,LDBDDB(U)	;GET ATTACHED JOB
	JUMPE	F,RICC3		;MAKE SURE THERE IS ONE
	MOVE	T1,DEVMOD(F)	;IS OWNING JOB ATTACHED TO TERMINAL,
	TLNE	T1,TTYATC	;OR JUST USING TERMINAL AS IO DEVICE?
	JRST	RICC3		;ATTACHED. OK TO DO CONTROL C
	MOVEI	S,IODERR	;NOT ATTACHED
	IORB	S,DEVIOS(F)	;GIVE JOB AN ERROR BIT
	PUSHJ	P,TTWAKE	;AND WAKE IT UP
	SETZM	DEVNAM(F)	;MAKE IT INVISIBLE TO DEVSRC
	PUSH	P,U		;SAVE U IN CASE DDB IS KILLED
	PUSHJ	P,PTYDET	;GET LINE FREE OF DDB
	POP	P,U		;RESTORE U
RICC3:	POP	P,T1		;RESTORE STACK LEVEL
	PUSHJ	P,TSETBI	;FORCE ACTION. CLEAR BUFFERS
	PUSHJ	P,TSETBO	;BOTH INPUT AND OUTPUT. COMCON HAS
				; BEEN FLAGGED BY CNCCHK
	MOVE	T2,FILXCP	;POINTER TO CONTROL C ECHO
	JRST	RIFRET		;STORE IT AND RETURN

RICC1:	MOVSI	T1,L2LCCS	;SET "↑C LAST IN" BIT
	IORM	T1,LDBBY2(U)	;NOT SECOND. STORE BIT.
	JRST	RICQ2		;AND TREAT AS RCV CHARACTER
;HERE ON RECEIPT OF A ↑D CHARACTER ;⊗ RICD CD CDSAV

	$LOW
RICD:	MOVEI	T2,LDRDSR	;DATASET OR REMOTE
	TDNE	T2,LDBDCH(U)	; ..
	JRST	RECINA		;YES--SAY ↑D
	HLRZ	T2,CD		;GET INSTRUCTION
	CAIE	T2,(JSR)	;BREAK POINT
	JRST	RECINA		;NO--IGNORE
	MOVEM	17,CDSAV+17	;SAVE 17
	MOVEI	17,CDSAV	;PLACE TO SAVE ACS
	BLT	17,CDSAV+16	;SAVE THEM
				;PLACE BREAKPOINT HERE . . .
CD::	MOVSI	17,CDSAV	;RESTORE ALL ACS
	BLT	17,17		;AND
	POPJ	P,		;RETURN FROM INTERRUPT
CDSAV:	BLOCK	20		;PLACE TO SAVE ACS AT CD BREAKPOINT
	$HIGH
;HERE ON CONTROL H (BACKSPACE) TO DETERMINE HOW TO TREAT ;⊗ RIBSP
;IN THE VARIOUS CASES LIKE APL ETC.

RIBSP:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,STOPCM
	HLLZ	P1,T1		;SAVE CHARACTER BITS
	LDB	T2,LDPAPL	;GET APL BIT
	JUMPN	T2,RECINA	;JUST STORE IN BUFFER (THIS APL)
IFN FTCAFE&FT2741,<
	MOVEI	T1,LDR2741	;IF 2741...
	TDNE	T1,LDBDCH(U)	;NON APL
	MOVEI	T3,377		;ACT LIKE RUBOUT
>;END OF FTCAFE&FT2741
	JRST	RIDELB
;HERE ON RECEIPT OF A CARRIAGE RETURN (CONTROL M) ;⊗ RICM RICO RINUL

RICM:	MOVEI	T2,L2RXON	;IS XON TRUE?
	TDNE	T2,LDBBY2(U)	;...
	JRST	RECINA		;YES. NOTHING SPECIAL. STORE.
	PUSHJ	P,RECINA	;NO. FIRST STORE THE C-R
	MOVEI	T3,12		;THEN GET A L-F (EVEN PARITY)
	JRST	RECIN1		;AND GO PRETEND IT WAS TYPED IN.

;HERE ON RECEIVE INTERRUPT OF A CONTROL O

RICO:	MOVEI	T1,LDROSU	;COMPLEMENT STATE OF OUTPUT SUPPRESS BIT
	XORM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
	DPB	T1,LDPSVC	;CLEAR ANY SAVED CHARACTER
IFN LDROSU&777,<PRINTX ?LDROSU AND LDPSVC CONFLICT>
	PUSHJ	P,TSETBO	;CLEAR OUTPUT BUFFER
	MOVE	T2,FILXOP	;POINTER TO ↑O ECHO
	JRST	RIFRET		;STORE AND RETURN

;HERE TO DISCARD INPUT CHARACTER SUCH AS NULL OR "USED" ↑O

	RINUL==CPOPJ##		;RETURN FROM RECINT.
;HERE ON RECEIVE INTERRUPT OF A CONTROL Q (XON) ;⊗ RICQ RICQ2A RICQ2

RICQ:	PUSH	P,T1		;SAVE CHARACTER BITS
	MOVSI	T1,L2LTAP	;HAS TERMINAL TAPE COMMAND BEEN TYPED?
	TDNN	T1,LDBBY2(U)	; ..
	JRST	RICQ2A		;NO. DON'T DO ANYTHING SPECIAL
	MOVEI	T1,L2RXON	;TURN ON BIT IN LINE CHAR WORD
	IORM	T1,LDBBY2(U)	; ENTER HERE FOR OTHER BITS TOO
	MOVEI	T1,ISRCHP
	PUSHJ	P,@LDBISR(U)	;TELL REMOTE STATION ABOUT THE ↑Q.
	POP	P,T1
	JRST	CHKXN1
RICQ2A:
IFN FTTPAG,<
	MOVSI	T1,LDLSTP+LDLSSO;CLEAR STOP BIT FOR TERMINAL OUTPUT
	ANDCAM	T1,LDBDCH(U)	;..
	MOVSI	T1,LPLPAG	;HAS "SET TERMINAL PAGE" BEEN ENABLED
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] ALWAYS SEND IF CROSSPATCHED
>				;[arpa] END IFN FTCIMP
	TDNN	T1,LDBPAG(U)	;..
	JRST	RICQ2		;NO, DON'T DO ANYTHING SPECIAL WITH ↑Q
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR PAGE COUNTER
	MOVEI	T1,ISRCHP	;TELL REMOTE STATION ABOUT ↑Q
	PUSHJ	P,@LDBISR(U)
	POP	P,T1		;RESTORE T1
	PJRST	TOPOKE		;AND GO START OUTPUT AGAIN
> ;IFN FTTPAG

RICQ2:	POP	P,T1		;RESTORE CHARACTER BITS
	JRST	RECINA		;AND ACCEPT THE CHARACTER
IFN FTMIC,<			;IF MIC ;⊗ RICP RICB2 RICB3 RICB RICT DOCTLT RICT1

;HERE ON RECEIVE INTERRUPT OF CONTROL P (PROCEED)

RICP:	SKIPN	T2,LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	RECINA		;NO - JUST RETURN
	TLO	T2,LDLCHK!LDLMCP;YES - SET UP ↑P FLAG
RICB2:	MOVEM	T2,LDBMIC(U)	;PUT WORD BACK
RICB3:	PJRST	MICWAK		;WAKE UP MIC

;HERE ON RECEIVE INTERRUPT OF CONTROL B (BREAK)

RICB:	SKIPN	T2,LDBMIC(U)	;IS MIC RUNNING FOR US?
	JRST	RECINA		;NO TREAT AS ORDINARY CHAR
	TLO	T2,LDLCHK!LDLMCB;YES - SET UP ↑B FLAG
	JRST	RICB2		;AND TREAT AS ↑P
> ;END OF IF MIC
;HERE ON A CONTROL T
IFN FTWATCH,<
RICT:	PUSHJ	P,DOCTLT	;PROCESS THE CONTROL-T
	  JRST	RECINA		;WE WANT TO STORE IT
	  JRST	[PUSHJ P,CLRPCT
		 JRST TTFORC]	;WE WANT TO DO USESTAT
	JRST	RIBUSY		;LINE ALREADY HAS A COMMAND

DOCTLT:
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] ALWAYS SEND IF CROSSPATCHED
>				;[arpa] END IFN FTCIMP
	LDB	T2,LDPRTC	;GET BIT FOR TERMINAL RTCOMPAT
	JUMPN	T2,CPOPJ##	;IF IT IS =1 GIVE NON-SKIP RETURN
	HLL	U,LDBDCH(U)	;GET DEVICE FLAGS
	TLNE	U,LDLSLV	;SLAVE?
	JRST	CPOPJ##		;YES--DO NOT FORCE CONTROL-T
	HRRZ	F,LDBDDB(U)	;GET LINKED DDB ADDRESS
	JUMPE	F,RICT1		;FORCE COMMAND IF ZERO
	MOVE	T2,DEVMOD(F)	;GET DEVICE BITS
	TLNN	T2,TTYATC	;CONTROLLING TERMINAL?
	JRST	CPOPJ##		;NO--JUST STORE THE CONTROL-T
RICT1:	MOVEI	T1,TTFCXW	;FORCE USESTAT
	SKIPL	(U)		;COMMAND ALREADY PENDING?
	JRST	CPOPJ1##	;NO--GIVE SINGLE SKIP
	JRST	CPOPJ2##	;YES--GIVE DOUBLE SKIP
> ;END FTWATCH
;HERE ON A CONTROL R ;⊗ RICR RICR1 RICR2

RICR:
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] ALWAYS SEND IF CROSSPATCHED
>				;[arpa] END IFN FTCIMP
	LDB	T2,LDPRTC	;RTCOMPATABILITY IN EFFECT?
	JUMPN	T2,RECINA	;JUMP IF SO, STORE CHARACTER IN THE INPUT BUFFER
	PUSHJ	P,FULLCQ	;COMMAND OR FULL CHARACTER SET?
	  JRST	RECINA		;YES, STORE CHARACTER
	SETZ	T3,		;ASSUME NOT A VIDEO TERMINAL
	PUSHJ	P,TTVID		;IS IT?
	  JRST	RICR2		;NO, NOTHING FANCY TO DO
	HLRZ	T3,TCRTAB+1(T1)	;ADDRESS OF EOL TABLE
	JUMPE	T3,RICR2	;VIDEO TERMINAL BUT CAN'T DO EOL
	MOVSI	T3,LDLUAR	;DOING CONTROL R
	PUSHJ	P,HPOS		;CURRENT HORIZONTAL POSITION
	LDB	T4,PRPOS	;LENGTH OF THE PROMPT
	CAMN	T2,T4		;CURSOR AT THE END OF THE PROMPT?
	JRST	RICR1		;YES, NOTHING TO SKIP OVER
	LDB	T2,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T2,RICR1	;IF NON-ZERO, THE PROMPT HAS BEEN SPACED OVER
	IORM	T3,LDBTTW(U)	;PROMPT HASN'T BEEN SPACED OVER SO INDICATE ↑R PROCESSING
	JRST	RICU2		;AND USE ↑U CODE TO SKIP THE PROMPT
RICR1:	ANDCAM	T3,LDBTTW(U)	;DONE WITH ↑R PROMPT PROCESSING
	DPB	T3,LDPSVC	;NO LEFT OVER CHARACTER
	DPB	T3,LDPFCT	;AND NO FILLER COUNT
	MOVEI	T2,0		;FILL POINTER
	PUSHJ	P,SETFLP	;ZAP
RICR2:	MOVEI	T1,TTFCXT	;RETYPE THE LINE
	SKIPGE	(U)		;IS THERE ALREADY AN OUTSTANDING COMMAND?
	JRST	RIBUSY		;YES, SAY BUSY
	PUSHJ	P,TTFORC	;FORCE THE RETYPE COMMAND
	JUMPN	T3,CPOPJ##	;ALL DONE IF NOT A HARDCOPY TERMINAL
	MOVE	T2,FLLBSC	;HARDCOPY,
	PJRST	RIFRET		; RETYPE ON A NEW LINE
;HERE ON RECEIVE INTERRUPT OF CONTROL S (XOFF) ;⊗ RICS STPOIP BEATIT RIBUSY BSYTXT GAWTXT

RICS:	PUSH	P,T1		;SAVE CHARACTER BITS
	MOVEI	T1,L2RXON	;CLEAR THIS BIT
	ANDCAM	T1,LDBBY2(U)	;IN LINE CHARACTERISTICS WORD
	MOVSI	T1,LDLSTP	;GET THE "STOPPED BY ↑S BIT"

IFN FTTPAG,<
	PUSHJ	P,STPOIP
	  JRST	RICQ2
	JRST	TPOPJ##
>
IFE FTTPAG,<JRST RICQ2>

IFN FTTPAG,<
STPOIP:	MOVSI	T2,LPLPAG	;HAS "SET TERMINAL PAGE" BEEN ENABLED?
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] ALWAYS SEND IF CROSSPATCHED
>				;[arpa] END IFN FTCIMP
	TDNN	T2,LDBPAG(U)	;...
	POPJ	P,		;NO, DON'T DO ANYTHING SPECIAL
	IORM	T1,LDBDCH(U)	;NO MORE OUTPUT UNTIL XON IS TYPED
IFN FTTVP,<
	PUSHJ	P,CLRPCT
>
	PUSHJ	P,SETCHP	;TELL FE'S TO STOP NOW
	JRST	CPOPJ1##
> ;IFN FTTPAG

BEATIT:	SKIPA	T2,[POINT 9,GAWTXT-1,26]
RIBUSY:	MOVE	T2,[POINT 9,BSYTXT]
	JRST	RIFRET

BSYTXT:	BYTE	(9)134,102,165,163,171,FLLFLG
GAWTXT:	BYTE	(9)123,164,341,356,344,240,341,154,157,356,145,FLLFLG

IFN FTTVP,< ;⊗ CLRPCT INCPCT CHKPCT
;ROUTINES TO IMPLEMENT 'TERMINAL PAGE N'

CLRPCT::SETZ	T2,
	DPB	T2,LDPPCT	;CLEAR COUNTER
	POPJ	P,

INCPCT:	LDB	T2,LDPPCT
	ADDI	T2,1
	DPB	T2,LDPPCT
;;	PJRST	CHKPCT

CHKPCT:
IFN FTCIMP,<			;[arpa] DISABLE AUTO STOP FOR IMPS
	SKIPE	LDBIMP(U)	;[arpa] cross patched out?
	  pjrst	ClrPct		;[arpa] yes.  clear count, don't stop
>				;[arpa]
IFN FTNET,<
	MOVE	T1,LDBREM(U)	;GET THE REMOTE BITS,
	TLNN	T1,LRLVTM	;  AND IF THIS IS A VTM LINE
>
	PUSHJ	P,PTBTCH##	;CHECK FOR BATCH PTY
	  POPJ	P,		;DISABLE AUTO STOP FOR BATCH OR VTM LINES
	LDB	T1,LDPPSZ	;PAGE SIZE
	JUMPE	T1,CPOPJ##	;IF NO AUTO PAGE SELECTED
	CAIGE	T2,-1(T1)	;COMPARE COUNT WITH SIZE, ALLOW FOR LAST LF
	POPJ	P,
	MOVSI	T1,LDLSSO	;GET "SCNSER STOPPED OUTPUT" BIT
	PUSHJ	P,STPOIP	;IF AT LIMIT, STOP OUTPUT, CLEAR COUNT
	  POPJ	P,		;STPOIP NON-SKIPS IF TERMINAL NO PAGE
	MOVE	T2,[POINT 9,[BYTE (9)207]] ;A LONE BELL
	PJRST	SETFLP		;REMIND THE USER OF TTY PAGE N
>
;PACKED IMAGE MODE (PIM) RECEIVE CHARACTER PROCESSING ;⊗ REPIM REPIM3 RPIM25 REPIM2 REPIM1

REPIM:
IFN FTTPAG,<
	MOVSI	T2,LPLPAG
	TDNN	T2,LDBPAG(U)	;HAS SET TERMINAL PAGE BEEN DONE?
	JRST	REPIM3		;NO, DON'T LOOK FOR XON/XOFF
	CAIE	T3,221		;THIS CHARACTER AN XON?
	CAIN	T3,21		;IN EITHER PARITY?
	JRST	RICQ		;YES, TREAT AS NON PIM XON
	CAIE	T3,223		;OR IS IT AN XOFF
	CAIN	T3,23		;
	JRST	RICS		;TREAT AS NON PIM XOFF IF SO
>;END OF FTTPAG
REPIM3:	MOVE	T2,LDBTIC(U)	;# OF CHARS INPUT
	CAMG	T2,RPIMWN	;TIME TO WARN HIM?
	JRST	REPIM2		;NO, NOT YET
	SUBI	T2,↑D20		;IS HE OVER 20 CHARS?
	CAMLE	T2,RPIMWN	;OVER CURRENT LIMIT?
	JRST	[MOVE	T1,LDBPAG(U)
		 TLNN	T1,LPLXOF	;SENT XOF YET?
		 JRST	RPIM25		;NO, DO IT NOW
		 JRST	RCHLT1]		;YES, EAT CHAR
RPIM25:	PUSHJ	P,SNDXOF	;SEND XOFF
	PUSHJ	P,RCVWAK
REPIM2:	SKIPG	TTFREN##	;ROOM IN CHUNK SPACE?
	JRST	RCHLT2		;NO, SHUT IT DOWN
	TRO	T3,400		;MARK NINTH BIT
	SCNOFF			;NO INTERRUPTS
	STCHK	T3,LDBTIP(U)	;PLACE CHARACTER IN BUFFER
	AOS	LDBTIC(U)	;INCREMENT COUNT
	SETZM	LDBECC(U)
	MOVE	T2,LDBTIP(U)
	MOVEM	T2,LDBECT(U)	;MAKE CHAR LOOK ECHOED
	SCNON			;ALLOW INTERRUPTS
	SKIPN	T2,LDBPBK(U)	;GET AND TEST BREAK CHARACTER WORD
	JRST	RCVWAK		;NOTHING SPECIFIED, BREAK ON ALL
	ANDI	T3,377		;CLEAR NINTH BIT FOR TEST
REPIM1:	LSHC	T1,9		;GET TEST CHARACTER
	XOR	T1,T3		;XOR WITH RECEIVED CHAR
	TRNN	T1,377		;MATCH?
	JRST	RCVWAK		;YES, BREAK CHAR, WAKE AND DISMISS
	JUMPE	T2,CPOPJ##	;DONE, DISMISS INTERRUPT
	JRST	REPIM1		;NO, TRY NEXT
SNDXOF::MOVSI	T1,LPLXOF	;GET THE "XOFF HAS BEEN SENT" BIT ;⊗ SNDXOF
	TDNE	T1,LDBPAG(U)	;HAVE WE SENT ONE?
	POPJ	P,		;IF SO, DON'T SEND TWO
	IORM	T1,LDBPAG(U)	;SET THE BIT SO WE DON'T SEND ANOTHER
	PUSH	P,T3		;ISR WILL CLOBBER THIS
	MOVEI	T3,1		;CODE TO SAY BUFFER LOW
	MOVEI	T1,ISRREM	;
	PUSHJ	P,@LDBISR(U)	;NOW CALL ISR
	  SKIPA	T2,FLPPXF	;ISR DID'T SEND IT. WE MUST
	JRST	T3POPJ		;XOFF SENT, POP T3 AND RETURN
	PUSHJ	P,SETXNP	;SET FILLER
	PUSHJ	P,TOPOKE	;MAKE SURE IT GETS OUT
	POP	P,T3		;RESTORE T3
	POPJ	P,		;RETURN

;HERE ON A CONTROL U AT INTERRUPT LEVEL ONLY ;⊗ RICU RICU1 RICU2 RICU3 RICU4

RICU:	PUSHJ	P,FULLCQ	;BREAK ON ALL CHARACTERS?
	  JRST RECINA		;YES. STORE THE ↑U IN BUFFER
	LDB	T1,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T1,RICU1	;JUMP IF NOT THE FIRST TIME
	PUSHJ	P,RIDLN		;BACKUP THE INPUT BUFFER TO THE LAST BREAK CHARACTER
	SKIPL	LDBDCH(U)	;LINE IDLE?
	JRST	RINUL		;NO, GO AWAY
	MOVE	T2,FILXUP	;ASSUME HARDCOPY \↑U<CRLF>
RICU1:	PUSHJ	P,TTVID		;VIDEO TERMINAL?
	  JRST	RIFRET		;NO, ECHO TRADITIONAL STUFF
RICU2:	PUSHJ	P,HPOS		;HORIZONTIAL POSITION
	LDB	T3,PRPOS	;LENGTH OF THE PROMPT
	CAMN	T2,T3		;AT THE END OF THE PROMPT?
	JUMPN	T3,RINUL	;YES, NOTHING TO DO
	HLRZ	T2,TCRTAB+1(T1)	;ADDRESS OF THE ERASE TABLE
	JUMPE	T2,[MOVE T2,FILXUP ;VIDEO TERMINAL BUT CAN NOT DO EOL
		    JRST RIFRET]
	JUMPE	T3,[MOVEI T1,1	;IF NO PROMPT, I.E. AT LEFT MARGIN,
		    AOJA T2,RICU4] ;CARRIAGE RETURN, ERASE END OF LINE
	LDB	T1,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T1,RICU3	;JUMP IF SPACING OVER THE PROMPT
	DPB	T3,LDPFCT	;REMEMBER NUMBER OF CHARACTERS TO SPACE OVER
	MOVE	T2,(T2)		;CARRIAGE RETURN
	MOVEI	T1,25		;DOING CONTROL U
	DPB	T1,LDPSVC	;REMEMBER THAT TO GET BACK HERE
	JRST	RIFRT1		;SET HPOS TO BEGINNING OF LINE AND TYPE CARRIAGE RETURN
RICU3:	CAIE	T1,1		;AT LAST CHARACTER OF THE PROMPT?
	SKIPA	T2,1(T2)	;NO, CURSOR RIGHT
RICU4:	MOVE	T2,2(T2)	;YES, CURSOR RIGHT, ERASE END OF LINE
	MOVSI	T4,LDLUAR	;CONTROL R BIT
	TDNE	T4,LDBTTW(U)	;PROCESSING CONTROL R?
	CAIE	T1,1		;YES, LAST CHARACTER OF THE PROMPT BEEN SPACED OVER?
	SOSA	T1		;NO, DECREMENT LENGTH OF THE PROMPT
	SKIPA	T4,[22]		;CONTROL R PROCESSING
	MOVEI	T4,25		;CONTROL U OR MORE CONTROL R
	DPB	T1,LDPFCT	;UPDATED FILLER REPEAT COUNTER
	DPB	T4,LDPSVC	;POST PROCESSING DISPATCH
	SKIPN	T1		;IF LAST CHARACTER,
	DPB	T1,LDPSVC	;NO POST PROCESSING
	JUMPE	T3,RIFRT1	;DONE IF NO PROMPT
	MOVEI	T3,40		;SPACE
	PUSHJ	P,ADJHP		;ADJUST HORIZONTAL POSITION 1 CHARACTER TO THE RIGHT
	JRST	RIDEL3		;SPACE OVER PROMPT CHARACTER
RIDLN:	PUSHJ	P,STOPCM	;STOP COMCON ;⊗ RIDLN RIDLN1 DELCHR DELCH3 ZAPIN
	SCNOFF			;NO INTERRUPTS
RIDLN1:	SKIPN	T1,LDBBKU(U)	;ANY BREAK POSITION SAVED?
	PJRST	TSETI2		;NONE THERE. MEANS ONLY THIS LINE IN BFR
	CAME	T1,LDBTIP(U)	;ANYTHING TO DELETE ?
	PUSHJ	P,DELCHR	;DELETE 1 CHAR
	  JRST	SONPPJ		;NOTHING LEFT TO DELETE
	JRST	RIDLN1		;LOOP OVER LINE

DELCHR:	SOSGE	T3,LDBECC(U)	;ANY LEFT TO ECHO?
	JRST	[SETZB	T3,LDBECC(U)	;CLEAR ECHO COUNT
		SOSL	LDBTIC(U)	;CHECK FOR UNECHOED INPUT
		JRST	DELCH3		;GO ERASE THOSE TOO
		SETZM	LDBTIC(U)	;CLEAR INPUT COUNT
		MOVE	T1,LDBTIP(U)
		MOVEM	T1,LDBECT(U)	;ENSURE EMPTY ECHO STREAM
		POPJ	P,]		;RETURN
DELCH3:	MOVE	T1,LDBTIP(U)	;GET INPUT PUTTER
	ADD	T1,[9B5]	;BACK 1 BYTE
	TLNE	T1,400000	;CHECK FOR BIT OVERFLOW
	SUB	T1,[<↑D36>B5+1]	;BACK TO PREVIOUS WORD
	MOVEI	T2,CK.BDY##(T1)	;SEE IF HIT HEADER WORD
	TRNN	T2,CK.BDY##	;WELL...
	JRST	[HLRZ	T1,CK.BTH##(T2)	;BACKUP
		JUMPE	T1,CL0STP	;IF A ZERO POINTER, MUST DIE
		ADD 	T1,[POINT 9,CK.BDY##,35] ;MAKE INTO BYTE POINTER
		JRST	.+1]
	MOVEM	T1,LDBTIP(U)	;STORE ADJUSTED POINTER
	JUMPN	T3,CPOPJ1##	;IF NO ECHO STREAM INTACT
	MOVEM	T1,LDBECT(U)	;NO, MAKE SURE IT STARTS CORRECTLY
	JRST	CPOPJ1##

ZAPIN:	SCNOFF			;OOPS, COUNT WENT NEGATIVE
	SETZM	LDBBKC(U)
	SETZM	LDBTIC(U)
	SETZM	LDBECC(U)	;CLEAN UP INPUT
	MOVE	T2,LDBTIT(U)	; COUNTERS AND
	MOVEM	T2,LDBTIP(U)	; POINTERS,
	MOVEM	T2,LDBECT(U)	; INCLUDING ECHO
	PJRST	SONPPJ
RWARN:	CAIGE	T2,TTIMAX	;IF HE IS WAY OVER, OR ;⊗ RWARN RECHLT RCHLT1 RCHLT2 RECVRG RECVR1
	SKIPG	TTFREN##	;WE ARE OUT OF CHUNKS
	JRST	RECHLT		;THROW AWAY THE INPUT CHARACTER
	PUSHJ	P,PTBTCH##	;CHECK IF OLD PTY OR BATCH
	  JRST	RWARNX		; CAN'T SEND XOFF
	PUSHJ	P,SNDXOF	;SEND XOFF
	JRST	RWARNX		;CONTINUE INPUT ROUTINE

RECHLT:	POP	P,T1		;RESTORE T1
RCHLT1::MOVE	T2,FLPBEL	;THIS IS TOO MUCH. TELL HIM
	PUSHJ	P,SETXNP	;SET FILLER FLAG
	MOVEI	T3,2		;CODE FOR CHAR NOT STORED
	MOVEI	T1,ISRREM
	PUSHJ	P,@LDBISR(U)	;TELL THE ISR CHAR NOT STORED
RCHLT2:	PUSHJ	P,TOPOKE	;START TYPING IF NEEDED (USUALLY NOT NEEDED)
	PJRST	ECHBRK		;TRY TO WAKE JOB, THEN
				;DISMISS INTERRUPT, JUNKING CHARACTER

RECVRG:	SCNOFF			;NO INTERRUPTS
	SKIPE	T1,LDBTIT(U)	;IF ANY POINTER
	JRST	RECVR1		;IF POINTER ALREADY EXISTS
	PUSHJ	P,GETCKZ	;GET A FREELIST CHUNK
	ADD	T1,[POINT 9,1,8];MAKE INTO A BYTE POINTER
	MOVEM	T1,LDBTIT(U)	;SET TAKER
RECVR1:	MOVEM	T1,LDBTIP(U)	;SET PUTTER BACK TO TAKER
	MOVEM	T1,LDBECT(U)	;AND THE ECHO POINTER
	SETZM	LDBBKU(U)	;BREAK LOCATION
	JRST	SONPPJ
;HERE ON A RUBOUT OR CONTROL W AT INTERRUPT LEVEL ;⊗ RIDEL RIDELB RIDELX RIDELY RIDELW RIDELZ

RIDEL:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,STOPCM
	HLLZ	P1,T1		;SAVE CHARACTER BITS
RIDELB:	PUSHJ	P,FULLCQ	;BREAK ON ALL CHARS, OR FCS?
	  JRST	RECINA		;YES. STORE THE RUBOUT
	LDB	P2,LDBTIP(U)	;GET CHARACTER TO BE ERASED
	ANDI	P2,177		;ONLY 7 BITS
	TLNE	P1,CHDELW	;CONTROL W?
	JRST	RIDELX		;IGNORE PAPER TAPE BITS
	MOVEI	T2,L2RXON	;PAPER TAPE IN EFFECT?
	TDNE	T2,LDBBY2(U)	;YES, DISCARD RUBOUT
	JRST	RINUL		;YES. DISCARD RUBOUT
RIDELX:	HLR	P1,CHTABL(P2)	;GET BITS FOR CHARACTER BEING DELETED
	MOVSI	T2,LDLNAN	;ALPHA-NUMERIC BIT
	LDB	T1,LDPFCT	;FILLER REPEAT COUNT
	JUMPN	T1,RIDELY	;JUMP IF NOT FIRST TIME
	TLNE	P1,CHDELW	;CONTROL W?
	TRNE	P1,CHPUNC	;SKIP IF NOT A PUNCTUATION CHARACTER
	JRST	RIDEL5		;NO, GO DO DELETE
	MOVEI	T1,1		;NOT REALLY A FILLER COUNT
	DPB	T1,LDPFCT	;BUT IT CAUSES US TO GET HERE AGAIN
	MOVSI	T2,LDLUAW!LDLNAN;INDICATE
	CAIE	P2,11		;A TAB?
	CAIN	P2,40		; OR A SPACE
	TLZ	T2,LDLNAN	;NO, ALPHANUMERIC NOT SEEN YET
	JRST	RIDELW		;GO DELETE THIS CHARACTER
RIDELY:	CAIE	P2,11		;A TAB?
	CAIN	P2,40		;OR A SPACE?
	JRST	[TDNN T2,LDBTTW(U) ;YES, ALREADY ERASED AN ALPHA-NUMERIC?
		JRST RIDEL5	;NO, ERASE IT
		JRST RIDELZ]	;YES, EVERY THING THE USER WANTED ERASED HAS BEEN
	TRNE	P1,CHPUNC	;IS THIS CHARACTER PUNCTUATION?
	JRST	RIDELZ		;YES, ALL DONE ERASING
RIDELW:	IORM	T2,LDBTTW(U)	;NO, REMEMBER THAT AN ALPHA-NUMERIC CHARACTER WAS SEEN
	JRST	RIDEL5		;AND GO DELETE THE CHARACTER
RIDELZ:	MOVSI	T1,LDLUAW!LDLNAN;NO LONGER PROCESSING CONTROL W
	ANDCAM	T1,LDBTTW(U)	;CLEAR ALPHA-NUMERIC REMINDER
	DPB	T1,LDPFCT	;AND FILLER REPEAT COUNT
	POPJ	P,		;THE WORD HAS BEEN ERASED SO GO AWAY
RIDEL5:	PUSHJ	P,TTVID ;⊗ RIDEL5 RIDEL6
	  TDZA	P3,P3
	HRRZ	P3,TCRTAB+1(T1)
	SKIPE	LDBECC(U)	;IF BAD DATA NOT YET ECHOED
	TLO	U,LDLNEC	;DON'T ECHO ERASURE
	SCNOFF			;NO INTERRUPTS HERE
	MOVE	T2,LDBTIP(U)	;GET ADDRESS OF INPUT STREAM
	CAMN	T2,LDBBKU(U)
	JRST	RIDEL1
	PUSHJ	P,DELCHR	;DELETE THE LAST INPUT CHARACTER
	  JRST	RIDEL1		;IF INPUT STRING DELETED
	SCNON			;ALLOW INTERRUPTS NOW
RIDEL6:	TLNN	P1,CHDEL	;RUBOUT?
	SETZ	P2,0		;NO--SPECIAL ECHO
IFN FTCIMP,<			;[arpa]
	MOVEI	T2,1		;[arpa] set A PHONY BYTE POINTER TO A NULL
	TLNN	U,LDLNEC	;[arpa] echoing?
	 skipe	LDBIMP(U)	;[arpa] yes.  crosspatched?
	  JRST	RIDEL3		;[arpa] crosspatched or not echoing: don't
				;[arpa]  type character after slash.
	DPB	P2,LDPSVC	;[arpa] SAVE FOR AFTER BACKSLASH
>				;[arpa]
ife FtCImp,<			;[arpa]
	TLNN	U,LDLNEC	;UNLESS NO ECHO
	DPB	P2,LDPSVC	;SAVE FOR AFTER BACKSLASH
	MOVEI	T2,1		;A PHONY BYTE POINTER TO A NULL
	TLNE	U,LDLNEC	;ECHO OFF?
	JRST	RIDEL3		;YES. DON'T OUTPUT
>				;[arpa]
IFN FTCAFE&FT2741,<
	MOVEI	T3,LDR2741
	TDNE	T3,LDBDCH(U)
	JRST	RIDEL3
>

;CONTINUED ON NEXT PAGE
;HERE TO ECHO THE RUBOUT ;⊗ RIDELA RIDELC RIDELD RIDEL7
	MOVE	T3,LDBDCH(U)	;IF ALREADY
	TDNN	T3,[LDLLCP,,LDRHLF] ;ECHOED, DON'T BUT DO UPDATE HPOS
	MOVE	T2,[POINT 9,[BYTE (9)210,0]]
	TLNN	P1,CHDEL	;RUBOUT OR BACKSPACE
	JRST	RIDEL4		;BACKSPACE (ECHO AS SELF)
	JUMPE	P3,RIDEL9	;A VIDEO TERMINAL?
	CAIE	P2,11		;A TAB?
	JRST	RIDEL7		;NO, ERASE 1 OR 2 CHARACTERS
	SCNOFF
	SKIPN	P1,LDBBKU(U)	;POSITION OF BREAK CHARACTER IN BUFFER
	MOVE	P1,LDBTIT(U)	;NONE, USE START OF THE BUFFER
	LDB	P2,PRPOS	;INITIALIZE CHARACTER COUNT
RIDELA:	CAMN	P1,LDBTIP(U)	;AT THE END?
	JRST	RIDELD		;YES
	LDCHK	T3,P1		;GET NEXT CHARACTER
	ANDI	T3,177		;JUST SEVEN BITS
	CAIE	T3,11		;A TAB?
	JRST	RIDELC		;NO
	TRZ	P2,7		;CLEAR LOW BITS
	ADDI	P2,10		;NEXT TAB STOP
	JRST	RIDELA		;LOOP OVER ALL CHARACTERS IN THE INPUT BUFFER
RIDELC:	MOVE	T1,CHTABL(T3)	;ECHO BITS
	TLNE	T1,CHUAE	;ECHO AS ↑X?
	ADDI	P2,1		;YES, COUNT IT AS 2 CHARACTERS
	AOJA	P2,RIDELA	;LOOP

;HERE WITH P2 = THE HORIZONTAL POSITION DUE TO TYPE IN

RIDELD:	SCNON
	PUSHJ	P,HPOS		;GET ACTUAL HORIZONTAL POSITION
	SUBI	T2,(P2)		;MINUS NUMBER OF CHARACTERS TYPED IN
	PUSHJ	P,BACKUP	;ADJUST HORIZONTAL POSITION
	JRST	RIDEL8		;ERASE BACK TO TAB STOP
RIDEL7:	MOVE	T1,CHTABL(P2)	;GET BITS TO CHECK FOR SPECIAL ECHOING
	MOVEI	T2,1		;ASSUME A SINGLE CHARACTER WAS ECHOED
	TLNE	T1,CHUAE	;REALLY ↑X ECHO?
	MOVEI	T2,2		;YES, ERASE 2 CHARACTERS
	PUSHJ	P,BACKUP	;ADJUST HORIZONTAL POSITION
RIDEL8:	MOVNI	T2,-10(T2)	;RELATIVE ADDRESS OF BYTE POINTER FOR ERASING ;⊗ RIDEL8 RIDEL9 RIDEL0 RIDEL4 BACKUP BACKU1 TTVID
	TRNE	T2,-10		;LINE WRAP AROUND?
	MOVEI	T2,0		;NOT QUITE RIGHT BUT RIGHT IS HARD
	ADD	T2,P3		;ADDRESS OF BYTE POINTER FOR ERASING
	MOVE	T2,(T2)		;BYTE POINTER TO ERASE TABLE
	MOVEI	T1,0		;ZERO LDPSVC
	DPB	T1,LDPSVC	;SO CHARACTER DOESN'T GET ECHOED AGAIN
	JRST	RIDEL3		;GO ERASE THE CORRECT NUMBER OF CHARACTERS
RIDEL9:	MOVEI	T1,0
	MOVE	T3,LDBDCH(U)	;DIFFERENT FORMAT IF LOCAL COPY
	TDNN	T3,[LDLLCP,,LDRHLF]
	MOVSI	T1,L2LDEL	;WAS DELETE LAST CHARACTER TOO?
	TDNN	T1,LDBBY2(U)	;IF SO, DON'T OUTPUT ANOTHER BACKSLASH
	JRST	RIDEL0		;NO. GO SET UP A BACKSLASH
	MOVEI	T2,1		;PHONY BYTE POINTER
	JRST	RIDEL3		;GO STORE AND RETURN

RIDEL0:	IORM	T1,LDBBY2(U)	;STORE THAT THIS IS DELETE
	AOS	LDBHPS(U)	;COUNT BACKSLASH POSITION
	MOVE	T2,FLLBSP	;GET POINTER TO BACKSLASH
	JRST	RIDEL3		;GO STORE AND RETURN

RIDEL4:	MOVEI	T3,10		;UPDATE HPOS BY
	PUSHJ	P,ADJHP		; MINUS ONE
	PJRST	RIDEL3		;GO STORE AND RETURN

;SUBROUTINE TO ADJUST HORIZONTAL POSITION WHEN ERASING CHARACTERS
;CALL WITH T2 = NUMBER OF POSITIONS TO BACKUP, RETURNS CPOPJ, T2 INTACT

BACKUP:	PUSH	P,T2		;SAVE T2
	MOVEI	T3,10		;BACKSPACE
BACKU1:	PUSHJ	P,ADJHP		;BACKUP 1 CHARACTER
	SOJG	T2,BACKU1	;LOOP FOR ALL
	JRST	T2POPJ		;RESTORE T2 AND RETURN

;SUBROUTINE TO DETERMINE IF THE CURRENT TERMINAL IS A VIDEO TERMINAL
; I.E., SPECIFIED AS SUCH BY THE USER TYPING A TTY TYPE COMMAND
; RETURNS CPOPJ IF NOT, CPOPJ1 IF SO, T1 POINTS AT CHARACTERISTICS TABLE
; ENTRY FOR THE TERMINAL TYPE

TTVID:	MOVSI	T1,LDLLCP	;LOCAL COPY BIT
	TDZE	T1,LDBDCH(U)	;LINE DOING OWN ECHOING
	POPJ	P,		;YES, AVOID VIDEO STUFF (T1=0)
	LDB	T1,LDPTTT	;GET TERMINAL TYPE AS SET BY COMMAND
	JUMPE	T1,CPOPJ##	;GO IF NONE SPECIFIED
	TRZE	T1,100		;CUSTOMER DEFINED TERMINAL TYPE ?
	MOVNI	T1,(T1)		;YES, NEGATIVE TABLE INDEX
	LSH	T1,1		;2 WORDS PER ENTRY
	SKIPE	TCRTAB+1(T1)	;SKIP IF NOT A VIDEO TERMINAL
	AOS	(P)		;IT IS!
	POPJ	P,		;RETURN
RIDEL1:	SCNON ;⊗ RIDEL1 RIFRET RIFRT1 RIDEL3 RIDEL2 RIALT RIALTO RIALT2 LNCREC LNRDHC LNREHC
	JUMPN	P3,RIDELZ
	SKIPL	LDBDCH(U)	;IS OUTPUT IN PROGRESS?
	JRST	RIDELZ		;YES.  DISCARD RUBOUT OR CONTROL W
	MOVE	T2,FLLBSC	;BACKSLASH CRLF
RIFRET:	MOVSI	T1,L2LDEL	;INSIDE BACKSLASHES?
	TDNN	T1,LDBBY2(U)	; ..
	IBP	T2		;NO. SKIP BACKSLASH
	ANDCAM	T1,LDBBY2(U)	;NO LONGER IN BACKSLASHES
RIFRT1:	PUSHJ	P,SCNBOL	;SET BACK TO START OF LINE
RIDEL3:	PUSHJ	P,SETFLP	;SETUP THE FILLER POINTER
IFN FTLINK,<			;[link]
	PUSHJ	P,CHKLKF##	;[link] SEND FILL POINTER TO LINKS
>				;[link]
	PUSHJ	P,TOPOKE	;START OUTPUT IF NEEDED
RIDEL2:	JRST	RINUL		;NOW DISCARD RUBOUT

;HERE ON ANY OF THE THREE ALTMODES, TO DECIDE ON CONVERSION TO STDALT
RIALT:	PUSHJ	P,RIALTO
IFN FTCIMP,<			;[arpa]
	skipe	LDBIMP(U)	;[arpa] crosspatched out to arpanet?
	  JRST	RECI2A		;[arpa] yes.  send as image.
>				;[arpa]
	JRST	RECINA

RIALTO:	MOVEI	T2,(T3)		;GET A COPY OF THE CHAR.
	ANDI	T2,177		;ISOLATE CHAR (REMOVE PARITY/IMAGE/ECHO BITS)
	CAIN	T2,STDALT	;CHECK FOR TRUE ESC
	POPJ	P,
	MOVEI	T1,0		;NO, ASSUME DATA CHAR
	MOVSI	T2,LPLALT	;CONVERT OLD ALTMODES?
	TDNN	T2,LDBPAG(U)	;DO WE CONVERT OLD ALTMODES?
	JRST	RIALT2		;YES, SO GO DO IT
	TLNE	U,LDLLCT	;NO, BUT SHOULD WE CONVERT TTY UC?
	TRC	T3,240		;YES, SO CHANGE IT
	POPJ	P,		;ALL DONE
RIALT2:	MOVEI	T3,STDALT	;YES USE THE STANDARD ALTMODE
	MOVE	T1,CHTABL(T3)	;NOW A BREAK, SO GET ITS BITS
	POPJ	P,		;STORE WHATEVER THIS DECIDED ON

IFN FTSCLC,<

;RECEIVE INTERRUPT ROUTINE FOR LINE CONTROL TRANSACTIONS

;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH
;  TRANSACTION CODE IN T3,
;  PHYSICAL LINE # IN U (IDX FOR LINTAB, LDBDCH, ETC)
;    U'S RANGE CHECKED BY INTERRUPT ROUTINE
;  AC'S & PDL SETUP


LNCREC::MOVE	U,LINTAB##(U)
	CAIN	T3,LNTEHC	;DISPATCH ON CHARACTER CODE IN T3
	JRST	LNREHC		;ENABLE HUNG CHECK
	CAIE	T3,LNTDHC
	POPJ	P,		;ILLEGAL CODE--IGNORE

LNRDHC:	MOVEI	T3,LDRSHC	;DISABLE HUNG CHECK
	IORM	T3,LDBDCH(U)	;  TURN ON LDRSHC
	POPJ	P,

LNREHC:	MOVEI	T3,LDRSHC	;TURN OFF LDRSHC
	ANDCAM	T3,LDBDCH(U)
	POPJ	P,
> ;END OF IFN FTSCLC
IFN FTMODM,<			;CODE INCLUDED ONLY IF MODEMS SUPPORTED ;⊗ DSCREC DSROFF
;RECEIVE INTERRUPT ROUTINE FOR DATASET TRANSACTIONS

;ENTER HERE FROM DEVICE-DEPENDENT ROUTINE WITH TRANSACTION CODE IN
; T3, DSCTAB INDEX IN U, RANGE ALREADY CHECKED BY INTERRUPT
; ROUTINE, AC'S AND PDL SET UP.


DSCREC::MOVE	T2,DSCTAB##(U)	;GET TABLE ENTRY FIRST
	TLNE	T2,DSCBLI	;IGNORE INTERRUPTS?
	POPJ	P,0		;YES. DO SO.
IFN FTPI,<PUSHJ P,SIGDSC>	;SIGNAL, DATA SET STATUS CHANGE
	CAIN	T3,DSTRNG	;DISPATCH ON CODES
	JRST	DSRRNG		;RING FROM DATAPHONE
	CAIN	T3,DSTON	;CARRIER ON?
	JRST	DSRON		;YES.
IFN FTDIAL,<
	CAIN	T3,DSTPND	;DIALLER WANT ANOTHER DIGIT
	JRST	DSRPND		;YES
>
DSROFF:	CAIN	T3,DSTOFF	;OFF INTERRUPT?
	TLNN	T2,DSCHWC	;YES. DID I THINK HE WAS ON?
	POPJ	P,0		;NO. FORGET IT.
	TLNN	T2,DSCSWC	;DO I THINK HE SHOULD BE ON?
	JRST	DSROF1		;NO. JUST GO CLEAR HIM OUT.
	MOVEI	T1,5		;YES. TIME OUT IN CASE OF BRIEF FAILURE
	DPB	T1,DSTMPL	;STORE IN TIME BYTE.
	MOVSI	T1,DSCHWC	;CLEAR THE CARRIER BIT
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCFAI	;AND FLAG POSSIBLE FAILURE CONDITION
	IORM	T1,DSCTAB##(U)	; ..
	POPJ	P,0		;LET CLOCK TIME HIM OUT NOW.
DSROF1::MOVSI	T1,DSCHWC!DSCSWC!DSCIC2 ;⊗ DSROF1 DSCCAL SIGDSC SIGDS1
	ANDCAM	T1,DSCTAB##(U)	;CLEAR ALL THESE BITS IN TABLE
IFN FTDIAL,<
	HRRZ	T1,DSCTAB##(U)	;GET TERMINAL NUMBER FOR THIS MODEM
	CAMN	T1,DSDUNI##	;DIALLER CODE USED BY IT?
	SETOM	TTYDDL##	;YES. CLEAR INTERLOCK TO FREE IT.
>
	MOVEI	T3,DSTOFF	;AND SEND OFF-COMMAND TO DEVICE
DSCCAL::MOVE	T2,DSCTAB##(U)	;T2 ← LINE NUMBER
	MOVEI	T1,ISRDSC	;DATASET CONTROL FUNCTION
	MOVE	T2,LINTAB##(T2)	;LDB ADDRESS
	PJRST	@LDBISR(T2)	;DISPATCH TO INTERUPT SERVICE

;SUBROUTINE TO SIGNAL DATA SET STATUS CHANGE
; ENTER T3=TRANSACTION CODE
IFN FTPI,<
SIGDSC::HRRZ	T1,LINTAB##(T2)	;GET LDB ADDRESS
	HRRZ	F,LDBDDB(T1)	;GET ADDRESS OF DDB
	MOVE	T4,J		;SAVE J
	JUMPE	F,SIGDS1	;ALL DONE IF ZERO
	LDB	J,PJOBN##	;GET JOB NUMBER
	JUMPE	J,SIGDS1	;JUMP IF JOB 0 (CAN THAT HAPPEN?)
	SIGNAL	C$DSET
	  JFCL
SIGDS1:	MOVE	J,T4		;RESTORE J
	POPJ	P,		;RETURN
> ;END IFN FTPI
;STILL IN FTMODM
DSRON: ;⊗ DSRON DSRON1
IFN FTDIAL,<
	TLNN	T2,DSCDLW	;IN DIALLER WAIT?
	JRST	DSRON1		;NO.
	MOVSI	T1,DSCDLW!DSCEON	;YES. CLEAR FLAGS FOR DIALLER
	ANDCAM	T1,DSCTAB##(U)	;IN TABLE IN CORE
	SETOM	TTYDDL##	;FREE UP DIALLER CODE
	MOVSI	T1,DSCDLC	;SET SUCCESSFUL COMPLETION BIT
	IORB	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
	PUSH	P,T2		;SAVE OLD STATUS
	PUSHJ	P,DSCWAK	;WAKE THE JOB, IF ANY STILL THERE.
	POP	P,T2		;RESTORE OLD BITS
> ;END IFN FTDIAL
DSRON1:
IFN FTCAFE,< ;CAFE'S SAY HELLO AFTER AUTOMATIC BAUD DETECT EVEN ON
;		LOCAL LINES. THIS ALLOWS USER TO GET SIGN ON MESSAGE
	HRRZ	T1,DSCTAB##(U)	;GET REAL LINE NUMBER
	HRRZ	T1,LINTAB##(T1)	;GET ADDRESS OF LDB
	MOVE	T1,LDBDCH(T1)	;GET DEVICE BITS
	TRNN	T1,LDRDSD	;IS THIS A REAL DATASET LINE?
	JRST	DSRON2		;NO--LOCAL TERMINAL JUST CAME UP
> ;END FTCAFE
	TLNE	T2,DSCHWC	;HE CAME ON. IS THAT NEWS TO ME?
	POPJ	P,0		;I THOUGHT HE WAS ON. FORGET IT.
	TLNN	T2,DSCSWC	;DO I WANT HIM ON?
	JRST	DSROF1		;NO. GO FORCE HIM OFF.
IFN FTGPO2B,<
	TLNE	T2,DSCFAI+DSCDLW	;A GPO2B MODEM CANNOT BE ALLOWED
	POPJ	P,		;TO RECOVER UNTIL THE TIMEOUT HAS
				;OCCURRED TO FORCE DETACH
				;BECAUSE 2B'S GENERATE SPURIOUS CARRIER
				;FROM DIAL TONE, BUSY, ETC.
>

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ DSRN1A DSRON2

	MOVSI	T1,DSCTMM+DSCFAI;YES. CLEAR TIME AND FAILURE BITS
	ANDCAM	T1,DSCTAB##(U)	;IN THE TABLE (STILL IN T2)
	MOVSI	T1,DSCHWC	;MARK THAT HE CAME ON
	IORM	T1,DSCTAB##(U)	;IN TABLE
	TLNE	T2,DSCFAI+DSCDLW;WAS ALL THIS A BRIEF FAILURE?
	POPJ	P,0		;YES. JUST DISMISS, HE'S BACK.
	MOVSI	T1,DSCBLI+DSCNCR;NO. NEW GUY. SET BLIND AND DELAY BITS
	HRRZ	F,LINTAB##(T2)	;LDB
	HRRZ	F,LDBDDB(F)	;DDB
	JUMPE	F,DSRN1A	;GO IF NO DDB
	MOVE	T4,DEVMOD(F)	;CHARACTERS
	TLNN	T4,TTYATC	;IF CONSOLE
	TRNN	T4,ASSCON!ASSPRG;AND NOT ASSIGNED
DSRN1A:	TLO	T1,↑D60		;SET TIME OUT
	IORM	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
DSRON2:	HRRZ	U,LINTAB##(T2)	;GET LDB ADDRESS FOR LINE
	PUSHJ	P,TSETBI	;CLEAR INPUT BUFFER
IFN FTNET,<
	MOVE	T1,LDBREM(U)	;GET THE REMOTE BITS
	TLNE	T1,LRLVTM	;  AND IF THIS IS A VTM LINE,
	PUSHJ	P,VTMDSO##	;  TURN CARRIER AND QUEUE LINE FOR SERVICE
>
	MOVSI	T1,L1LOFL
	ANDCAM	T1,LDBOFL(U)
	SKIPGE	DEBUGF##
	POPJ	P,
	HRRZ	F,LDBDDB(U)	;GET DDB
	JUMPN	F,CPOPJ##	;DO NOT RUN INITIA IF THERE IS A
				; JOB ON THE LINE
	MOVEI	T1,TTFCXH	;GET HELLO COMMAND INDEX
	JRST	TTFORC		;FORCE HELLO COMMAND
> ;END CONDITIONAL ON FTMODM
TTFRC1:	AOS	(P) ;⊗ TTFRC1 TTFORC DSRRNG DSRRN2 DSRRN1 DSCDET
TTFORC::DPB	T1,LDPCMX	;STORE FORCED COMMAND INDEX
	MOVSI	T1,LDBCMR+LDBCMF;FORCED COMMAND REQUEST.
	JRST	COMST1		;SET COMMAND COUNT, IF NEEDED

IFN FTMODM,<
DSRRNG:	MOVE	T1,STATES##	;PHONE RINGING. MAY I ANSWER?
	TRNE	T1,ST.NRL	;CHECK THE SCHEDULE COMMAND WORD
	POPJ	P,0		;NOT ALLOWED. IGNORE.
	PUSH	P,U		;SAVE PTR TO DSCTAB
	HRRZ	U,DSCTAB##(U)	;GET REAL LINE NUMBER
	HRRZ	U,LINTAB##(U)	;GET ADR OF LDB
IFN FTCAFE,<
	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNN	T1,LDRDSD	;IS THIS A DATASET LINE?
	JRST	UPOPJ##		;NO
>;END OF IFN FTCAFE
	HRRZ	F,LDBDDB(U)	;DDB PTR
	JUMPE	F,DSRRN2	;NO JOB, ALL OK
	MOVE	T1,DEVMOD(F)	;DEVICE BITS
	TLNN	T1,TTYATC	;CONTROLLING TTY?
	JRST	DSRRN2		;NO, SO NO JOB
				;IF WE GET HERE, WE HAVE RING ON LINE
				; WITH A JOB, WHICH IS NOT SUPPOSED TO
				; HAPPEN.  TO PREVENT SECURITY PROBLEMS,
				; WE DETATCH THE JOB
	PUSHJ	P,DSCDET	;DETACH OR KILL IF NOT LOGGED IN.
DSRRN2:	POP	P,U		;RESTORE DSCTAB PTR
	MOVEI	T3,0		;CLEAR VARIOUS
	DPB	T3,DSTMPL	; TIMERS
	MOVSI	T1,DSCFAI+DSCTMM;CLEAR THE MOMENTARY FAILURE BIT
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCSWC+↑D30	;TURN ON ALLOW BIT, AND TIME.
DSRRN1:	IORM	T1,DSCTAB##(U)	;IN DATASET CONTROL TABLE
	MOVEI	T3,DSTON	;SEND A TURN-ON COMMAND TO DEVICE-
	PJRST	DSCCAL		; DEPENDENT ROUTINE, AND DISMISS


DSCDET:	MOVEI	T1,TTFCXD	;DO THE DETACH BY
	PJRST	TTFORC		; FORCING A .BYE
IFN FTDIAL,< ;⊗ DSRPND DSRPN1
DSRPND:	TLNE	T2,DSCEON	;SENT ALL DIGITS?
	POPJ	P,0		;YES. IGNORE REQUEST
	MOVEI	T1,↑D60		;ONE MINUTE FROM SENDING DIGIT
	DPB	T1,DSTMPL	;INTO TIME-OUT OF DATASET
	MOVSI	T1,DSCEON	;FLAG END OF NUMBER SENT, IF TRUE.
	ILDB	T3,TTYDDA##	;GET ANOTHER DIGIT
	CAIN	T3,17		;END OF NUMBER CODE?
	JRST	DSRPN1		;YES
	ADDI	T3,DSTPND	;CONVERT TO TRANSACTION CODE FOR XXXINT
	PJRST	DSCCAL		;AND SEND IT OUT
	

DSRPN1:	IORM	T1,DSCTAB##(U)	;SET FLAG IN TABLE
	POPJ	P,0		;DON'T SEND NUMBER
> ;END OF FTDIAL
> ;END OF FTMODM CONDITIONAL

IFE FTMODM,<DSCREC==:CPOPJ##>
	SUBTTL	KI10 CONSOLE TERMINAL SERVICE ;⊗ CTYINT CTYIN CTYOUT

IFN FTKI10,<
CTYINT::CONSO	TTY,40		;INPUT OR OUTPUT
	JRST	CTYOUT		;OUTPUT.
CTYIN:	DATAI	CTY,T3		;INPUT. GET THE CHARACTER
	JRST	RECINT		;GO PROCESS IT

CTYOUT:	CONO	CTY,200+SCNCHN##	;CLEAR THE OUTPUT BIT
	JRST	XMTINT		;AND GO SERVICE INTERRUPT
>;END IFN FTKI10
	SUBTTL	KS10 CTY AND KLINIK TERMINAL SERVICE ;⊗ CT0INT CTYIN1 CTYIN2 CTYIN3 CTYIN4

IFN FTKS10,<
CT0INT::SKIPN	.CPFEF##	;HAS FRONT END INTERRUPTED ?
	JRST	.-1		;ON THROUGH SKIP CHAIN
	WRPI	CLRCTY##	;CLEAR THE INTERRUPT
	SETZM	.CPFEF##	;CLEAR THE FLAG
	JSR	SCNSAV##	;SAVE AC'S ETC.
	MOVE	T3,KLIIWD	;GET KLINIK INPUT WORD
	TRNN	T3,KLIIVL	;IS THERE INPUT?
	  JRST	CTYIN1		;NO--PROCEED
	SETZM	KLIIWD		;YES--CLEAR IT
	MOVEI	U,KLILIN##	;GET KLINIK LINE NUMBER
	PUSHJ 	P,RECINT	;PASS TO SCNSER
CTYIN1:	MOVE	U,LINTAB+KLILIN## ;LDB FOR KLINIK LINE
	SKIPL	LDBDCH(U)	;IS KLINIK OUTPUT ACTIVE?
	SKIPE	KLIOWD		;YES--IS OUTPUT WORD AVAILABLE?
	JRST	CTYIN2		;NO--PROCEED
	MOVEI	U,KLILIN##	;KLINIK LINE NUMBER
	PUSHJ	P,XMTINT	;SEE IF MORE TO TYPE
CTYIN2:	SKIPN	T3,CTYIWD	;ANY CTY INPUT?
	  JRST	CTYIN3		;NO--PROCEED
	SETZM	CTYIWD		;YES--CLEAR IT
	MOVEI	U,CTYLIN##	;CTY LINE NUMBER
	PUSHJ	P,RECINT	;PASS TO SCNSER
CTYIN3:	MOVE	U,LINTAB+CTYLIN## ;GET LDB ADR FOR CTY
	SKIPL	LDBDCH(U)	;IS CTY TYPING ?
	SKIPE	CTYOWD		;AND IS OUTPUT WORD FREE ?
	JRST	CTYIN4		;NOT TYPING OR STILL BUSY
	MOVEI	U,CTYLIN##	;LINE NUMBER FOR CTY
	PUSHJ	P,XMTINT	;TRY TO TYPE MORE STUFF
CTYIN4:	POPJ	P,		;RETURN
>;END IFN FTKS10
	SUBTTL	FILLERS AND SIMULATION ROUTINES ;⊗ SETFLO SETFLI

;ROUTINE TO SET UP FILLERS FOR OUTPUT CHARACTERS
;CALL WITH
;	MOVE	T3,CHARACTER
;	MOVE	T1,CHTABL(T3)
;	PUSHJ	P,SETFLO
;	  <CHARACTER NEEDS FILLERS, ALREADY SETUP>
;	<CHARACTER NEEDS NO FILL>


SETFLO:	TLZ	T1,CHUAE+CHALT+CHCRE	;THESE ECHO MODES NOT USED ON OUTPUT
	TLO	T1,CHFILO	;FLAG OUTPUT-FILLER REQUEST
	JRST	SETFL2		;REST OF ROUTINE SAME AS ON INPUT

;ROUTINE TO SET FILLER POINTER FOR INPUT CHARACTERS (ECHOING)

SETFLI:	TLNE	T1,CHALT	;IS THIS A POSSIBLE ALTMODE?
	PUSHJ	P,RIALTO	;YES, SEE IF IT IS A REAL ALTMODE
IFN FTCAFE,<
IFN FT2741,<
	MOVE	T2,LDBDCH(U)	;IS THIS A 2741
	TRNE	T2,LDR2741	; ??
	JRST	CPOPJ1##	;YES--FILLERS DONE BY PDP-11
> ;END FT2741
> ;END FTCAFE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ SETFL2

;COMMON CODE FOR SETFLI/SETFLO

SETFL2:	MOVE	T2,LDBHPS(U)	;GET HORIZONTAL POSITION COUNTER
	TLNE	U,LDLDLR	;USER WANT DOLLAR SUPPRESSED?
	TLZ	T1,CHALT+CHUAE+CHCRE	;YES. DO SO.
	TLNE	T1,CHUAE	;WILL ↑X BE ADDED?
	ADDI	T2,2		;YES. ADD 2 TO HPOS
	TLNE	T1,CHALT	;IS IT GETTING A DOLLARSIGN?
	ADDI	T2,1		;YES. COUNT IT.
	JUMPLE	T2,SETFI1	;IF NOT AT END OF SCREEN
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] IF CROSSPATCHED, NO FREE CRLF
>				;[arpa]
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  JRST	SETFI1		;IT IS, NO FREE CRLF
	MOVE	T2,LDBDCH(U)	;GET THE CHARACTERISTICS WORD
	TLNE	T2,LDLNFC	;USER WANT FREE <CR><LF>?
	JRST	SETFI1		;NO. FORGET IT.
;	PJRST	SETCRF		;YES, FALL INTO SETCRF
;⊗ SETCRF SETCR2 SETCR5
;SETCRF -- ROUTINE TO SETUP A FREE CRLF POINTER

SETCRF:	PUSHJ	P,SCNBOL	;RESET LINE COUNTERS IN ANY CASE
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] IF CROSSPATCHED, NO FREE CRLF
>				;[arpa]
	TRNE	T2,LDRREM	;IS THIS A NETWORK VIRTUAL TERMINAL?
	JRST	SETCR5		;YES, THEN NO FILLER (THE REMOTE COMPUTER
				; WILL SUPPLY THE FREE <CR><LF>, WE NEED
				; MERELY NOTE THAT A NEW LINE IS STARTING)
	LDB	T2,LDPFLC	;GET FILL CLASS
SETCR2:	MOVE	T2,FLLCRP(T2)	;GET APPROPRIATE POINTER TO STRING
	PUSHJ	P,SETFLP	;SETUP THE APPROPRIATE FILLER POINTER
	MOVSI	T2,LDLLCP	;DON'T ECHO INPUT CHARACTER AFTER FREE CRLF
	TLNN	T1,CHFILO	; BUT IF OUTPUT, DON'T EAT A CHARACTER
	TDNN	T2,LDBDCH(U)	;IF LOCAL COPY IS SET
	DPB	T3,LDPSVC	;SAVE CHARACTER FOR LATER
	POPJ	P,		;NON-SKIP RETURN (NEEDED CRLF)

SETCR5:	MOVE	T2,T3		;SCRATCH COPY OF CHARACTER
	ANDI	T2,177		;JUST SEVEN-BIT ASCII
	CAIL	T2,40		;IS CHARACTER A
	CAIL	T2,177		; NORMAL PRINTING ASCII GRAPHIC?
	TLNE	T1,CHALT!CHUAE	;NO, CONTROL, IF EITHER "$" OR "↑X" FORM
	AOS	LDBHPS(U)	;THEN COUNTS AS A PRINTING CHARACTER
	TLNE	T1,CHUAE	;IN ADDITION, IF "↑X" FORM
	AOS	LDBHPS(U)	; THEN COUNTS AS TWO PRINTING CHARACTERS
	PUSHJ	P,INCPCT	;COUNT LINES OUTPUT FOR TTY PAGE N
	HLL	U,LDBDCH(U)	;GET LEFT-HALF CHARACTERISTICS
	TLNN	U,LDLSSO	;DID INCPCT HIT A PAGE BREAK?
	JRST	CPOPJ1##	;NO, JUST OUTPUT THE FIRST CHARACTER

;HERE IF THE FREE <CR><LF> THAT WE KNOW THE REMOTE IS ABOUT TO OUTPUT
;(AS SOON AS IT SEES THE CHARACTER IN T3) WILL ALSO BREAK THE PAGE LIMIT.
;WE MUST SUPPLY THE FREE <CR><LF> AND THEN STOP IN ORDER TO MAKE THE
;REMOTE BEHAVE THE SAME AS LOCALLY-OWNED TERMINALS. THIS RELYS ON THE
;FACT THAT XMTSPC WILL FORCE OUT THE FILLER POINTER EVEN IF THE LINE
;IS XOFFED - A DUBIOUS FEATURE AT BEST.

	PUSHJ	P,SCNBOL	;OOPS - RE-CLEAR HORIZONTAL POSITION

;TECHNICALLY, INCPCT SHOULD BE UNDONE, SINCE THE <CR><LF> COMING WILL
;LEAVE IT OFF BY ONE, BUT THE XON NEEDED TO GET OUT OF THE STUCK STATE
;WILL RESET THE PAGE COUNTER, SO . . .

	MOVEI	T2,4		;FILLER POINTER WITH BELL
				;SEE SETCR2
	JRST	SETCR2		;GO OUTPUT A NEW LINE
SETFI1:	TLNN	T1,CHFIL	;THIS CHAR NEED FILLERS? ;⊗ SETFI1 SETFI0 ZFLPOP FLLPOP SETFI2 SETFI3
	JRST	SETFI2		;NO.
SETFI0:	PUSH	P,T3		;SAVE THE CHARACTER
				;*** CHAR MUST BE AT 0(P) FOR SIMULATORS ***
				;*** EVEN THOUGH THIS IS BAD PRACTICE
IFN FT2741&FTCAFE,<
	MOVE	T3,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TRNE	T3,LDR2741	;IS THIS A 2741?
	  JRST	ZFLPOP		;YES - DC76 WILL DO FILLERS
	MOVE	T3,(P)
>;END OF IFN FT2741&FTCAFE
	ANDI	T3,177		;JUST 7 BITS (NO PARITY)
	CAIG	T3,15		;NEED TO CALL ROUTINE FOR IT?
	JRST	@SETFLD-10(T3)	;YES. GO DO IT.
	CAIL	T3,21		;CONTROL Q THRU T?
	JRST	SETFI6		;YES. THEY HAVE SPECIAL HANDLERS TOO
	PUSHJ	P,SETFLC	;GET FILL CLASS
	JUMPE	T2,ZFLPOP	;NO. USER WANT FILLER SUPPRESSED?
	SKIPA	T2,FILLP1	;NO. ASSUME ONE FILLER IS ENOUGH
ZFLPOP:	MOVEI	T2,0		;POINTER FOR NO FILLERS
FLLPOP:	PUSHJ	P,SETFLP	;SETUP THE FILLER POINTER
	AOS	-1(P)		;RESTORE CHARACTER AND SKIP RETURN
	JRST	T3POPJ##	;SKIP IS BECAUSE T3 IS TO BE TYPED
				; SKIP IS BECAUSE T3 IS TO BE TYPED

SETFI2:	TLNN	T1,CHUAE+CHALT+CHCRE	;ECHO AS ↑X OR $ ?
	JRST	CPOPJ1##	;NO. NOTHING SPECIAL. JUST SEND.
	TLNE	T1,CHALT	;ALTMODE?
	JRST	SETFI3		;YES.
	TLNE	T1,CHCRE	;ECHO AS UPARROW X CRLF?
	JRST	SETFI4		;YES.
	TRC	T3,300		;TURN ON 100 BIT, COMPLEMENT PARITY
	DPB	T3,LDPSVC	;STORE FOR AFTER THE UPARROW
	SKIPA	T2,FLLUPA	;GET POINTER TO UPARROW CONST

SETFI3:	MOVE	T2,FLLDLR	;GET POINTER TO DOLLARSIGN GRAPHIC
	AOS	LDBHPS(U)	;ADVANCE HORIZONTAL POSITION
	PJRST	SETFLP		;SET FILLER POINTER AND RETURN
;CAN ONLY GET HERE FOR ↑U,↑Z OR ↑C. OTHERS NOT STORED IN INPUT BUFFER ;⊗ SETFI4 SETFI6 SETFI7

SETFI4:	ANDI	T3,177		;NO PARITY
	PUSHJ	P,SCNBOL	;SET COUNTERS BACK TO BEGINNING OF LINE
	MOVEI	T2,0		;0 BYTE POINTER
	CAIN	T3,"C"-100	;CONTROL C?
	MOVE	T2,FILXCP	;YES. ITS POINTER
	CAIN	T3,"Z"-100	;CONTROL Z?
	MOVE	T2,FILXZP	;YES. ITS POINTER
	IBP	T2		;SKIP BACKSLASH
	PJRST	SETFLP		;STORE ECHO POINTER AND FORCE IT OUT

SETFI6:	TLNN	U,LDLDLR	;ECHOING GRAPHICS INHIBITED?
	TLNE	T1,CHFILO	;IS THIS FOR INPUT OR OUTPUT OF ↑Q-↑T?
	JRST	SETFI7		;NO GRAPHICS. JUST THROW ON A RUBOUT.
	MOVEI	T2,2		;LENGTH OF PRINT REPRESENTATION
	ADDM	T2,LDBHPS(U)	;ADD TO HORIZONTAL POSITION COUNTER
	MOVE	T2,STFLT2-21(T3);GET ECHO POINTER FOR CONTROL Q-T
	SOS	-1(P)		;NON-SKIP RETURN
	JRST	FLLPOP		;STORE FILLER AND RETURN

SETFI7:	PUSHJ	P,SETFLC	;GET FILL CLASS
	SKIPE	T2		;FILL 0?
	MOVE	T2,FILLP1	;NO, USE A FILLER
	PJRST	FLLPOP		;STORE FILLER AND GO HOME
;SETFLC -- ROUTINE TO SETUP THE FILLER CLASS FOR A LINE ;⊗ SETFLC SETXNP SETFLP SETFPT SETFP1

SETFLC:	
IFN FTNET,<
	MOVEI	T2,LDRREM	;REMOTE BIT
	TDNE	T2,LDBDCH(U)	;REMOTE STATION DOES ITS OWN FILL
	TDZA	T2,T2		;SO RETURN INDEX OF ZERO
>
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] IF CROSSPATCHED, let remote fill.
>				;[arpa]
	PUSHJ	P,PTBTCH##	;CHECK FOR REGULAR PTY
	  TDZA	T2,T2		;IT IS, USE FILLER CLASS 0
	LDB	T2,LDPFLC	;ELSE GET FILL CLASS FROM LDB
	POPJ	P,		; AND RETURN



;ROUTINE TO SETUP AN "XON CLASS" FILLER POINTER
;CALL
;	MOVE	T2,FILL POINTER
;	PUSHJ	P,SETXNP
;	<ALWAYS RETURN HERE>

SETXNP::SCNOFF			;GET SCNSER INTERLOCK
	MOVEM	T2,LDBXNP(U)	;STORE FILL POINTER
	PJRST	SETFP1		;SET LDLFCP & RETURN



;ROUTINE TO SETUP A FILLER POINTER. SETS LDLFCP IF APPROPRIATE.
;CALL
;	MOVE	T2,FILLER POINTER
;	PUSHJ	P,SETFLP
;	<ALWAYS RETURNS HERE>
;ENTER AT SETFPT IF SCNOFF

SETFLP::SCNOFF
SETFPT::MOVEM	T2,LDBFLP(U)	;STORE IN LINE BLOCK
	JUMPE	T2,SONPPJ	;CLEARED WORD, JUST RETURN
SETFP1:	MOVSI	T2,LDLFCP
	IORM	T2,LDBDCH(U)	;SET FLAG FOR XMTCHR
	JRST	SONPPJ		;NON-SKIP RETURN, TO FORCE OUT
;DISPATCH TO SET FILLERS FOR SOME CHARACTERS ;⊗ SETFLD FILLH FILLK2 FLLFLG FILXCP FILXCD FILXUP FILXUD FILXOP FILXOD FILXZP FILXZD STFLT2 FILXQD FILXRD FILXSD FILXTD

SETFLD:	EXP	FILLH,FILLI,FILLJ,FILLK,FILLL,FILLM
;POINTERS, CODE AND DATA FOR FILLER CHARACTERS

;HERE FOR A BACKSPACE AND HARDWARE VERTICAL TAB

FILLH:
FILLK2:	PUSHJ	P,SETFLC	;GET FILLER CLASS FOR LINE
	MOVE	T2,FILLHP(T2)	;GET FILLER BYTE POINTER
	JRST	FLLPOP		;GO STORE AND RETURN.

FLLFLG==:1				;FLAG TO ADD A CRLF AFTER THIS FILLER

FILXCP:	POINT	9,FILXCD	;CONTROL C ECHO
FILXCD:	BYTE	(9) 134,336,303,FLLFLG	;BACKSLASH, ↑C CRLF
FILXUP:	POINT	9,FILXUD	;CONTROL U ECHO
FILXUD:	BYTE	(9) 134,336,125,FLLFLG	;BACKSLASH, ↑U CRLF
FILXOP:	POINT	9,FILXOD	;CONTROL O ECHO
FILXOD:	BYTE	(9) 134,336,317,FLLFLG	;BACKSLASH, ↑O CRLF
FILXZP:	POINT	9,FILXZD	;POINTER TO CONTROL Z ECHO
FILXZD:	BYTE	(9) 134,336,132,FLLFLG	;BACKSLASH, ↑Z CRLF

;DISPATCH FOR ↑Q TO ↑T ECHOES

STFLT2:	POINT	9,FILXQD
	POINT	9,FILXRD
	POINT	9,FILXSD
	POINT	9,FILXTD

FILXQD:	BYTE	(9) 336,321,21,377,0	;↑Q
FILXRD:	BYTE	(9) 336,322,22,377,0	;↑R
FILXSD:	BYTE	(9) 223,336,123,0	;↑S
FILXTD:	BYTE	(9) 24,336,324,0	;↑T
FILLKP:					;POINTERS FOR BS AND VT ;⊗ FILLKP FILLHP FILLP2 FILLLP FILLJP FILLP1 FLLCRP FLLCR0 FLLCR1 FLLCR2 FLLCR3 FLLUPA FLLDLR FLLUP1 FLLBSP FLLBS1 FLLBSC FLLCOP FLLCO1 FLLDMY FLLDMP
FILLHP:	0				;NO FILLERS
FILLP2:	POINT	9,FILLRZ,8	;2 FILLERS
	POINT	9,FILLRY,8	;6 FILLERS
	POINT	9,FILLRY,8	;6 FILLERS

FILLLP:					;POINTERS FOR FORMFEED
	0				;NO FILLERS
	POINT	9,FILLRX,26	;12 FILLERS
	POINT	9,FILLER,17	;21 FILLERS
	POINT	9,FILLER,17	;21 FILLERS

FILLJP:					;POINTERS FOR LINEFEED
	0				;NO FILLERS
FILLP1:	POINT	9,FILLRZ,17	;1 FILLER
	POINT	9,FILLRY,8	;6 FILLERS
	POINT	9,FILLRY,8	;6 FILLERS

FLLCRP::POINT	9,FLLCR0	;TABLE OF POINTERS FOR FREE CRLF'S
	POINT	9,FLLCR1
	POINT	9,FLLCR2
	POINT	9,FLLCR2

	POINT	9,FLLCR3
FLLCR0:	BYTE	(9) 215,12,0	;DATA FOR FREE CRLF'S
FLLCR1:	BYTE	(9) 215,215,12,377,0
FLLCR2:	BYTE	(9) 215,215,12,377,377,377,377,377,0

FLLCR3:	BYTE	(9) 215,12,207,0
FLLUPA:	POINT	9,FLLUP1	;POINTER TO UPARROW
FLLDLR:	POINT	9,FLLUP1,17	;POINTER TO DOLLARSIGN
FLLUP1:	BYTE	(9) 336,0,44,0	;UPARROW AND $, WITH PARITY
FLLBSP:	POINT	9,FLLBS1	;POINTER TO BACKSLASH
FLLBS1:	BYTE	(9) 134,0,134,FLLFLG	;BACKSLASH DATA
FLLBSC:	POINT	9,FLLBS1,17	;POINTER TO BACKSLASH - CRLF

FLLCOP:	0				;FILLERS FOR OUTPUT CR
	POINT	9,FLLCO1,17	;ONE EXTRA CR
	POINT	9,FLLCO1
	POINT	9,FLLCO1
FLLCO1:
;[dm1500]BYTE	(9) 215,215,215,0	;EXTRA CARRIAGE RETURNS
	BYTE	(9) 377,377,377,0	;[dm1500] fill with rubouts: some
					;[dm1500]  terminals (datamedia's)
					;[dm1500]  add <LF> to <CR>.

;DUMMY FILLER

FLLDMY:	BYTE(9)	0,0,0,0
FLLDMP:	POINT	9,FLLDMY
VT06BP:	POINT	9,VT06TB ;⊗ VT06BP VT06EP VTXXBP VTXXEP V100EP HP26EP DM15EP
	POINT	9,VT06TB+2,8
	POINT	9,VT06TB+4,17
	POINT	9,VT06TB+6,26
	POINT	9,VT06TB+10,35
	POINT	9,VT06TB+13,8
	POINT	9,VT06TB+15,17
	POINT	9,VT06TB+17,26

VT06EP:	POINT	9,VT06EL
	POINT	9,VT06E1
	POINT	9,VT06E2
	POINT	9,VT06E3

VTXXBP:	POINT	9,VTXXTB
	POINT	9,VTXXTB,26
	POINT	9,VTXXTB+1,17
	POINT	9,VTXXTB+2,8
	POINT	9,VTXXTB+2,35
	POINT	9,VTXXTB+3,26
	POINT	9,VTXXTB+4,17
	POINT	9,VTXXTB+5,8

VTXXEP:	POINT	9,VTXXEL
	POINT	9,VTXXE1
	POINT	9,VTXXE2
	POINT	9,VTXXE3

V100EP:	POINT	9,VTXXEL
	POINT	9,V100E1
	POINT	9,V100E2
	POINT	9,V100E3

;[hp2621]  HP2621 terminal support
HP26EP: POINT	9,VTXXEL	;[hp2621]
	POINT	9,HP26E1	;[hp2621]
	POINT	9,HP26E2	;[hp2621]
	POINT	9,HP26E3	;[hp2621]

;[dm1500] data media 1500 support terminal support
DM15EP:	POINT	9,VTXXEL	;[dm1500]
	POINT	9,DM15E1	;[dm1500]
	POINT	9,DM15E2	;[dm1500]
	POINT	9,DM15E3	;[dm1500]
VT06TB:	BYTE	(9)	377,377,377,210,240,377,377,377 ;⊗ VT06TB VT06EL VT06E1 VT06E2 VT06E3 VTXXTB VTXXEL VTXXE1 VTXXE2 VTXXE3 V100E1 V100E2 V100E3 HP26E1 HP26E2 HP26E3 DM15E1 DM15E2 DM15E3
	BYTE	(9)	210,377,377,377,210,240,377,377
	BYTE	(9)	377,210,377,377,377,210,240,377
	BYTE	(9)	377,377,210,377,377,377,210,240
	BYTE	(9)	377,377,377,210,377,377,377,210
	BYTE	(9)	240,377,377,377,210,377,377,377
	BYTE	(9)	210,240,377,377,377,210,377,377
	BYTE	(9)	377,210,240,377,377,377,210,377
	BYTE	(9)	377,377,210,240,377,377,377,210
	BYTE	(9)	0

VT06EL:	BYTE	(9)	215,377,377,377,0
VT06E1:	BYTE	(9)	30,377,377,377,0
VT06E2:	BYTE	(9)	30,377,377,377,36,377,377,377,0
VT06E3:	BYTE	(9)	215,377,377,377,36,377,377,377,0

VTXXTB:	BYTE	(9)	210,240,210,210,240,210,210,240
	BYTE	(9)	210,210,240,210,210,240,210,210
	BYTE	(9)	240,210,210,240,210,210,240,210
	BYTE	(9)	0

VTXXEL:	BYTE	(9)	215,0
VTXXE1:	BYTE	(9)	33,303,0
VTXXE2:	BYTE	(9)	33,303,33,113,0
VTXXE3:	BYTE	(9)	215,33,113,0

V100E1:	BYTE	(9)	33,333,303,0
V100E2:	BYTE	(9)	33,333,303,33,333,113,0
V100E3:	BYTE	(9)	215,33,333,113,0

;[hp2621] HP2621 terminal support
;[hp2621] 215 = cr / <esc>C = forward cursor /<esc>K  = erase EOL

HP26E1:	BYTE	(9)	33,103,0		;[hp2621] forward one
HP26E2:	BYTE	(9)	33,103,33,113,0		;[hp2621] forward, erase line
HP26E3:	BYTE	(9)	215,33,113,0		;[hp2621] erase entire line

;[dm1500] data media terminal support
;[dm1500] 215 = <cr> /234 = forward cursor / 35 = erase EOL

DM15E1:	BYTE	(9)	234,0		;[dm1500] forward one
DM15E2:	BYTE	(9)	234,35,0	;[dm1500] forward, erase line
DM15E3:	BYTE	(9)	215,35,0	;[dm1500] erase entire line
;HERE TO GENERATE FILLERS OR SIMULATION FOR HORIZONTAL TAB ;⊗ FILLI FILL1 FILLI1 FILLJ FILLK FILLK1 SCCHPJ
;PHPOS IS UPDATED ALREADY, BUT POHPOS HAS THE PREVIOUS POSITION,
;LOW ORDER THREE BITS, SO THE TAB SIMULATION CAN BE DONE FROM IT.

FILLI:
IFN FTNET,<
	MOVEI	T2,LDRREM	;REMOTE BIT
	TDNE	T2,LDBDCH(U)	;REMOTE STATION DOES OWN FILL
	JRST	ZFLPOP		;SO NO FILLERS
>
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	TLNN	U,LDLTAB	;USE TAB, OR MAKE IT OUT OF SPACES?
	JRST	FILLI1		;SPACES.
	TRNN	T2,1		;FILL CLASS 0 OR 2?
	JRST	ZFLPOP		;YES, NO FILLERS
	LDB	T1,POHPOS	;GET OLD POSITION ON LINE.
	MOVE	T2,FILLP2	; ASSUME UNDER HALFWAY TO TAB STOP
	TRNE	T1,4		;TRUE?
FILL1:	MOVE	T2,FILLP1	;NO. NEED JUST ONE FILLERS.
	JRST	FLLPOP		;GO STORE FILLER POINTER, SEND
				; TAB, AND RETURN.

;HERE TO MAKE A TAB OUT OF SOME SPACES.

FILLI1:	MOVEI	T3,640		;WILL USE SPACES. DISCARD SAVED
				; TAB ON STACK.
				; IMAGE BIT BECAUSE HPOS NOW RIGHT
	LDB	T1,POHPOS	;GET LOW 3 BITS OF OLD HPOS
	MOVE	T2,FILLIP(T1)	;GET CORRESPONDING POINTER TO SPACES
	JRST	SCCHPJ		;GO STORE, TYPE FILLERS AND SVC
				; AND RETURN.

FILLJ:
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FILLJP(T2)	;GET THE CORRESPONDING FILLERS
	JRST	FLLPOP		;FOR A LINEFEED, AND RETURN.

FILLK:	TLNE	U,LDLFRM	;THIS LINE HAVE FORM MOTION?
	JRST	FILLK2		;YES. USE SAME FILLERS AS BACKSPACE
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FLLKSP(T2)	;GET SIMULATION POINTER
FILLK1:	MOVEI	T3,12		;CLOBBER THE VT OR FF ON STACK
SCCHPJ:	DPB	T3,LDPSVC	;SAVE CHARACTER FOR AFTER FILLERS
	PUSHJ	P,SETFLP	;SETUP THE FILLER POINTER
	JRST	T3POPJ##	;AND NON-SKIP RETURN TO CAUSE FILLERS
FILLL:	TLNE	U,LDLFRM	;THIS LINE HAVE FORM MOTION? ;⊗ FILLL FILLL1 FILLM FILLM1 RETYPE RETYPL STOPCM
	JRST	FILLL1		;YES. GO SET FILLERS.
	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FLLLSP(T2)	;GET POINTER TO LINEFEEDS AND FILLERS
	JRST	FILLK1		;GO TO COMMON CODE

FILLL1:	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FILLLP(T2)	;AND FILLER POINTER
	JRST	FLLPOP		;GO STORE THIS POINTER AND RETURN

FILLM:	TLNE	T1,CHFILO	;NO, IS THIS FOR IN OR OUTPUT?
	JRST	FILLM1		;OUTPUT.
	MOVEI	T2,L2RXON	;XON BIT
	TDNE	T2,LDBBY2(U)	;XON IN EFFECT?
	JRST	ZFLPOP		;NO LOCAL, OR XON TRUE. THEREFORE,
	MOVE	T2,LDBDCH(U)	;GET DCH BITS BACK
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] CROSSPATCHED?
	 TRNE	T2,LDRIMP	;[arpa] OR AN IMP?
	  JRST	ZFLPOP		;[arpa] YES, LET REMOTE DO IT
>				;[arpa]
	TDNN	T2,[XWD LDLLCP,LDRHLF]	;EITHER TYPE OF LOCAL COPY?
					; NO FREE CRLF, OR IT WILL BE ECHOED
	JRST	FILLM1		;NO LOCAL COPY
	PUSHJ	P,SETFLC	;GET FILL CLASS
	MOVE	T2,FLLCRP(T2)	;NEED A FREE LINEFEED.GET CRLF
	IBP	T2		;AND COUNT IT PAST CR
	JRST	FLLPOP		;AND GO STORE RESULT

FILLM1:	PUSHJ	P,SETFLC	;GET FILLER CLASS
	MOVE	T2,FLLCOP(T2)	;GET FILLERS FOR CR OUTPUT
	JRST	FLLPOP		;GO STORE AND RETURN

RETYPE::
IFN FTNET,<			;IF WE HAVE THE NETWORK, WE
	SKIPGE	LDBREM(U)	; BETTER MAKE SURE THAT THIS ISN'T A VTM
	POPJ	P,		; CAUSE IF IT IS, THE CHUNKS ARE ALL
>				; MESSED UP AND WE WILL "RCC"
	SCNOFF
	SKIPN	T1,LDBBKU(U)	;SKIP IF BREAK IN BUFFER
	MOVE	T1,LDBTIT(U)	;ELSE GET START OF BUFFER
	PUSHJ	P,CTISBP	;STORE THE BYTE POINTER
	HRRZM	U,.CPCML##	;REMEMBER LINE # FOR DEBUGGING
	SCNON
RETYPL:	PUSHJ	P,CCTYI		;GET A BYTE.
				;YOU MAY THINK WE SHOULD CALL COMTYI, YOU
				; ARE WRONG.
	CAIN	T3,12		;DONE?
	JRST	[SETZM .CPCML##	;YES
		 POPJ P,0]	;RETURN
	PUSHJ	P,USEARO	;TYPE OUT CHAR, IN ARROW MODE
	JRST	RETYPL		;LOOP FOR MORE

STOPCM:	PUSH	P,T1		;SAVE T1
	MOVEI	T1,0		;GET A ZERO AND USE IT TO
	SCNOFF			;INTERLOCK W.R.T. CCTYI
	PUSHJ	P,CTISBP	;  SAY THERE IS NO COMMAND ON THIS LINE
	SCNON			;RETURN INTERLOCK
	JRST	TPOPJ##		;RESTORE T1 AND RETURN
;DATA SENT OUT AS FILLERS ;⊗ FILLER FILLRX FILLRY FILLRZ KSPACE KLINEF FILLIP FLSLD0 FLSKD0 FLSLD1 FLSKD1 FLBPXF FLLKSP FLLLSP FLBLXF FLPBEL FLPXOF FLPPXF FLLXON FLPXON

FILLER:	BYTE	(9) 377,377,377,377	;BLOCK OF 23 RUBOUTS
	BYTE	(9) 377,377,377,377
FILLRX:	BYTE	(9) 377,377,377,377
	BYTE	(9) 377,377,377,377
FILLRY:	BYTE	(9) 377,377,377,377
FILLRZ:	BYTE	(9) 377,377,377,0	;ZERO TERMINATES THE STRING

KSPACE:	BYTE	(9) 240,240,240,240	;BLOCK OF 7 SPACES.
	BYTE	(9) 240,240,240,0

KLINEF:	BYTE	(9) 12,12,12,12	;BLOCK OF 7 LINEFEEDS
	BYTE	(9) 12,12,12,0

FILLIP:	POINT	9,KSPACE	;POINTERS FOR TAB SIMULATION
	POINT	9,KSPACE,8
	POINT	9,KSPACE,17
	POINT	9,KSPACE,26
	POINT	9,KSPACE,35
	POINT	9,KSPACE+1,8
	POINT	9,KSPACE+1,17
	0

FLSLD0:	BYTE	(9) 12,12,12,12	;LINEFEEDS W/O FILLERS.
FLSKD0:	BYTE	(9) 12,12,12,0	; ..

FLSLD1:	BYTE	(9) 377,377,12,377	;LINEFEEDS WITH 2 FILLERS.
	BYTE	(9) 377,12,377,377
	BYTE	(9) 12,377,377,12
FLSKD1:	BYTE	(9) 377,377,12,377
	BYTE	(9) 377,12,377,377
	BYTE	(9) 12,377,377,0
FLBPXF:	BYTE	(9) 223,0,0,0
FLLKSP:	POINT	9,FLSKD0	;POINTERS TO SIMULATE ↑K
	POINT	9,FLSKD0
	POINT	9,FLSKD1
	POINT	9,FLSKD1

FLLLSP:	POINT	9,FLSLD0	;POINTERS TO SIMULATE ↑L
	POINT	9,FLSLD0
	POINT	9,FLSLD1
	POINT	9,FLSLD1

FLBLXF:	BYTE	(9) 207,223,377,0	;DATA - BELL,XOFF,RUBOUT
FLPBEL::POINT	9,FLBLXF	;POINTER TO BELL-XOFF-RUBOUT
FLPXOF:	POINT	9,FLBLXF,8	;POINTER TO XOFF AND RUBOUT
FLPPXF::POINT	9,FLBPXF	;POINTER TO XOFF WITH NO FILL
FLLXON:	BYTE	(9) 21,377,0	;DATA - XON,RUBOUT
FLPXON:	POINT	9,FLLXON	;POINTER TO XON-RUBOUT
	SUBTTL	TIMING ROUTINE ;⊗ SCNSEC SCNSIL

;SUBROUTINE CALLED EVERY SECOND AT CLOCK LEVEL.
;CHECKS FOR IRMA. TIMES IMAGE INPUT. RUNS MODEMS.

SCNSEC::MOVEI	J,TCONLN##	;PREPARE TO SEARCH LINE TABLE
	PUSHJ	P,SAVE2##
IFN FTMP,<MOVE P2,.CPCPN##>	;CPU #
	SETZM	%SCNAL
SCNSIL:	MOVE	U,LINTAB##(J)	;GET ADR OF LDB
	MOVE	T1,LDBDCH(U)	;GET THE CHARACTERISTICS
IFN FTMP,<			;IF SMP, CHECK WHICH CPU WE'RE ON
	LDB	T2,LDPCPU	;GET # OF LINE'S OWNER
	TRNE	T1,LDRREM	;BUT IF IT'S A NETWORK LINE, ONLY DO
	MOVE	T2,BOOTCP##	;  TIMING ON THE BOOT CPU
	CAIE	T2,(P2)		;ARE WE ON RIGHT CPU
	JRST	SCNSIS		;IF WRONG CPU, SKIP THIS LINE
>
	TLNE	T1,LDLIMI	;IMAGE INPUT STATE?
	PUSHJ	P,SCSIMG	;YES. GO TIME IT
	MOVE	T1,LDBDCH(U)	;SCSIMG CAN CLOBBER THIS
	JUMPL	T1,SCNSIN	;IF IDLE?
	AOS	%SCNAL
IFN FTCIMP,<			;[arpa]
	TRNE	T1,LDRSHC!LDR2741!LDRPTY!LDRIMP ;[arpa] YES - HUNG CHECKING?
>				;[arpa]
IFE FTCIMP,<			;[arpa]
	TRNE	T1,LDRSHC!LDR2741 ;YES - HUNG CHECKING?
>				;[arpa]
	JRST	SCNSIN		;NO
IFN FTHDPX,<
	MOVE	T1,LDBBY2(U)	;GET HALF DUPLEX FLAGS
	TLNE	T1,L2LHD3+L2LHD4	;DURING ECHO FAILURE?
	JRST	SCNSIN		;YES. DON'T DO HUNG CHECK
>
	MOVSI	T1,LPLIRM	;SET UP SYNC BIT
	TDNE	T1,LDBPAG(U)	;ON FROM 1 SECOND AGO?
	JRST	[PUSHJ P,TOREQ	;REQUEUE SO OUTPUT STARTS ;⊗ SCNSIN SCNSIS
		 MOVSI	P1,L1LOFL
		 MOVEI	T1,ISROFL
		 PUSHJ	P,@LDBISR(U)
		   IORM	P1,LDBOFL(U)
		 JRST   SCNSIN]	;LOOK AT NEXT LINE
	IORM	T1,LDBPAG(U)	;TURN ON SYNC BIT FOR THIS SECOND
SCNSIN:	MOVE	T1,LDBTIC(U)
	ADD	T1,LDBECC(U)
	SKIPE	T1
	AOS	%SCNAL
	SKIPL	LDBOFL(U)
	JRST	SCNSIS
	MOVSI	P1,L1LOFL
	MOVEI	T1,ISROFL
	PUSHJ	P,@LDBISR(U)
	  SKIPA
	ANDCAM	P1,LDBOFL(U)
SCNSIS:	SOJGE	J,SCNSIL
IFN FTMP,<
	SKPCPU	(0)		;ONLY ON MASTER
	PJRST	@.CPISR##
>
	SOSGE	SNDCTR##
	SETZM	SNDCTR##
	AOS	T2,%SCNAL
	CAIGE	T2,20
	MOVEI	T2,20
	MOVE	T1,TTFREN##
	IMULI	T1,↑D12
	IDIV	T1,T2
	CAIGE	T1,↑D80
	MOVEI	T1,↑D80
	EXCH	T1,TIWRNN	;STORE NEW LIMIT AND GET PREVIOUS
	MOVEM	T1,TIWRN1	;STORE PREVIOUS
	MOVE	T1,TIWRNN	;GET NEW BACK
	CAIGE	T1,↑D600	;IF IT ISN'T AT LEAST 600
	MOVEI	T1,↑D600	; THEN MAKE IT 600
	MOVEM	T1,RPIMWN	;AND SAVE
IFE FTMODM,<PJRST @.CPISR##>	;CALL EACH ISR
				;ELSE FALL THRU INTO DATASET ROUTINE
IFN FTMODM,< ;⊗ DSCSEC DSCSLP DSCSC2 DSCSNY DSCSC1

;ROUTINE TO DO ONCE-A-SECOND TIMING OF MODEMS. TIMES OUT INTERVALS
;FROM RING TO CARRIER ON, FROM CARRIER ON TO LEGAL COMMAND,
; AND FROM CARRIER OFF TO HANG UP.

DSCSEC:	SKIPL	J,DSCPTR##	;GET DATASET CONTROL POINTER
	JRST	DSCSC1		;THERE ARE NONE IN THIS CONFIGURATION
	HLLZS	J		;CLEAR RIGHT HALF FOR INDEXING
DSCSLP:	MOVE	T1,DSCTAB##(J)	;GET TABLE ENTRY
	TLNE	T1,DSCBLI	;BLIND STILL ON?
	JRST	DSCSC3		;YES.
	SCNOFF			;CAN'T ALLOW INTERRUPTS HERE
	LDB	T3,DSTIMP	;GET THE TIME SINCE RING OR CARRIER FAILURE
	SOSL	T3		;COUNT IT DOWN. WAS IT 0?
	DPB	T3,DSTIMP	;NO. STORE NEW VALUE
	JUMPN	T3,[SCNON	;UNLESS NEWLY 0, ALLOW INTERRUPTS
		    JRST DSCSNY]; AND GO TO NEXT
	MOVSI	T3,DSCFAI+DSCSWC;CLEAR FAIL AND SOFTWARE BITS
	ANDCAB	T3,DSCTAB##(J)	; IN CORE
	SCNON			;OK FOR INTERRUPTS NOW.
IFN FTDIAL,<
	TLNE	T3,DSCDLW	;IN DIALLER WAIT?
	JRST	DSCSDF		;YES. DIALLER HAS FAILED.
>
	HRRZ	U,LINTAB##(T1)	;GET THE LDB ADDRESS
				; OF THE RELATED TERMINAL LINE
IFN FTNET,<
	MOVE	T1,LDBREM(U)	;GET THE REMOTE STATUS BITS,
	TLNE	T1,LRLVTM	;  AND IF THIS IS A VTM LINE
	PUSHJ	P,VTMDSF##	;  SIGNAL CARRIER OFF TO THE REMOTE
>
	PUSHJ	P,LDBCLR	;CLEAR OUT LDB STATUS
	HRRZ	F,LDBDDB(U)	;SEE IF THERE'S A JOB.
	JUMPE	F,DSCSC2	;SKIP THIS IF NO JOB
	MOVE	T1,DEVMOD(F)	;MAY BE A JOB. GET MODE WORD.
	TLNN	T1,TTYATC	;CONTROLLING A JOB.
	JRST	DSCSC2		;NOT A CONTROLLING TERMINAL. NO COMMAND

	PUSHJ	P,DSCDET	;DETACH THE GUY (.BYE)
DSCSC2:	MOVEI	T3,DSTOFF	;SOFTWARE CODE TO TURN OFF DATASET
	MOVEI	U,0(J)		;TABLE ADDRESS AS LINE NUMBER
	PUSHJ	P,DSCCAL	;SEND TO APPROPRIATE HARDWARE DEVICE
DSCSNY:	AOBJN	J,DSCSLP	;COUNT THROUGH ALL LINES
DSCSC1:	PJRST	@.CPISR##	;DO ISR TIMING
;STILL IN FTMODM
DSCSC3:	MOVSI	T3,DSCBLI	;SET FOR BLIND BIT ;⊗ DSCSC3 DSCSDF DSCWAK DSTIMP DSTMPL
	TLNE	T1,DSCNCR	;NEW CARRIER BIT STILL ON?
	MOVSI	T3,DSCNCR	;YES. CLEAR IT INSTEAD
	ANDCAM	T3,DSCTAB##(J)	;CLEAR BIT IN TABLE
	JRST	DSCSNY		;AND GO ON TO NEXT MODEM

IFN FTDIAL,<
DSCSDF:	SETOM	TTYDDL##	;CLEAR DIALLER CODE INTERLOCK
	MOVEI	U,0(J)		;COPY TABLE INDEX
	PUSHJ	P,DSROF1	;CLEAR OUT THE HARDWARE FOR THIS LINE.
	MOVSI	T1,DSCDLF	;FLAG THAT DIALLING LOST
	IORB	T1,DSCTAB##(J)	; ..
	PUSHJ	P,DSCWAK	;WAKE THE SLEEPING JOB, IF ANY
	JRST	DSCSNY		;LOOK FURTHER THRU DSCTAB

DSCWAK:	MOVE	T1,LINTAB##(T1)	;GET THE LDB ADDRESS FOR THIS DATASET'S TERMINAL
	HRRZ	F,LDBDDB(T1)	;GET THE DDB, IF ANY
	SKIPE	T1		;ANY?
	LDB	T1,PJOBN##	;YES. GET JOB NUMBER
	JUMPE	T1,CPOPJ##	;ANY?
	PJRST	WAKJOB##	;YES. WAKE IT.
> ;END OF FTDIAL

DSTIMP:	POINT	6,DSCTAB##(J),17	;POINTERS TO TIME BYTE
DSTMPL:	POINT	6,DSCTAB##(U),17	;SAME BUT DIFFERENT AC INDEX
				;MUST AGREE WITH DSCTMM
> ;END OF FTMODM
;SUBROUTINE TO TIME THE IMAGE MODE INPUT STATE, SET END OF FILE IF ;⊗ SCSIMG SCSIM2 SCSIM1
;IT TIMES OUT, AND FORCE CONTROL C UNLESS SLAVED ON SECOND TIME-OUT


SCSIMG:	PUSH	P,J		;SAVE COUNTER. WILL BE CLOBBERED.
	LDB	T3,LDPTIM	;GET THE IMAGE TIME BYTE
	SOSL	T3		;COUNT IT DOWN. TOO LOW?
	DPB	T3,LDPTIM	;NO STORE NEW VALUE.
	JUMPG	T3,IPOPJ##	;IF NO TIMEOUT YET, GO BACK TO LOOP
	HRRZ	F,LDBDDB(U)	;GET LINE'S JOB DATA BLOCK
	JUMPE	F,SCSIM2	;NO JOB? TIME AGAIN
IFN FTCIMP,<			;[arpa]
	MOVEI	T1,INDSTM##	;[arpa] HAS USER DISABLED IMAGE MODE TIMEOUT?
	TDNE	T1,DEVIOS(F)	;[arpa] ...
	  JRST	IPOPJ##		;[arpa] yes.  don't check.
>				;[arpa]
	MOVSI	S,FRCEND	;CAUSE UUO ROUTINE TO FORCE END
	TDNE	S,DEVIOS(F)	;ON YET?
	JRST	SCSIM1		;ON ALREADY. PANIC.
	IORB	S,DEVIOS(F)	;NO. SET IT NOW AND TIME OUT AGAIN
SCSIM2:	MOVEI	T3,IMGTIM	;SET TIME TO NEXT PANIC
	DPB	T3,LDPTIM	;STORE IN TIME BYTE
	PUSHJ	P,RCVWAK	;AND WAKE UP JOB
	JRST	IPOPJ##		;GO RESTORE J AND RETURN

SCSIM1:	MOVSI	S,TTYATC	;GET A BIT
	TDNE	S,DEVMOD(F)	;IS THIS AN I/O DEVICE?
	TLNE	T1,LDLSLV	;IS THIS A SLAVE TERMINAL?
	JRST	SCSIM2		;YES. CAN'T DO CONTROL C
	PUSHJ	P,CNCMOD	;NO. SET TO COMMAND LEVEL
	MOVSI	T1,LDBCMF	;FORCE COMMAND
	DPB	T1,LDPCMX	;CONTROL C INDEX
	IORM	T1,LDBDDB(U)	;AND FLAG COMMAND DECODER
	PUSHJ	P,COMSET	;WAKE UP COMMAND ROUTINE,
	JRST	IPOPJ##		;RESTORE AC AND RETURN
;OUTPUT SERVICE ROUTINE FOR CTY ;⊗ CTYSTO CTYTYO CTYTY1 KLITYO

IFN FTKI10!FTKS10,<
CTYSTO::MOVEI	T1,.CPCTQ##	;POINT TO CTY OUTPUT QUEUE HEADER
	PUSHJ	P,TOTAKE	;GET A LINE NUMBER (CHECK QUEUE)
	  POPJ	P,		;NONE WAITING
	SKIPGE	LDBDCH(U)
	PUSHJ	P,XMTCHR	;GET NEXT OUTPUT CHARACTER
	  POPJ	P,		;LINE IS NOW IDLE
	PUSHJ	P,CLRIRM	;CLEAR IRMA BH
CTYTYO:	ANDI	T3,377		;REMOVE JUNK
IFN FTKI10,<
	DATAO	CTY,T3		;SEND THE CHARACTER
>
IFN FTKS10,<
	HRRZ	T1,LINTAB##+KLILIN##
	CAIN	T1,(U)		;KLINIK LINE?
	JRST	KLITYO		;YES--GO TO IT
	IORI	T3,CTYOVL	;SET VALID FLAG
	MOVEM	T3,CTYOWD	;PUT IN OUTPUT WORD
CTYTY1:	RDAPR	T1		;GET CPU PI LEVEL
	ANDI	T1,SP.PIA	; AND ONLY THE PI LEVEL
	WRAPR	SP.SSF+SP.IFE(T1) ;INTERRUPT THE 8080
>
IFN FTHDPX!FTTRACK,<
	DPB	T3,LDPECK	;FOR LIGHTS ONLY (CTY IS FDX)
>
	POPJ	P,0		;AND RETURN
IFN FTKS10,<
KLITYO:	IORI	T3,KLIOVL	;SET VALID BIT
	MOVEM	T3,KLIOWD	;PUT CHAR IN OUTPUT WORD
	JRST	CTYTY1		;GO INTERRUPT 8080
>;END IFN FTKS10
>;END IFN FTKI10!FTKS10
;ROUTINE TO ADJUST HORIZONTAL POSITION COUNT FOR CHARACTER TO ;⊗ ADJHP ADJHP3 ADJHP2 ADJHP1 T23PPJ
;OUTPUT FROM BUFFER. CALL WITH T3, U SET UP.

ADJHP:	PUSH	P,T3		;SAVE CHARACTER
	ANDI	T3,177		;JUST CHARACTER BITS
	CAIL	T3,177		;RUBOUT
	JRST	T3POPJ##	;DOESN'T SPACE
	CAIL	T3,40		;NON-IMAGE CONTROL CHARACTER?
	JRST	ADJHP1		;NO, SIZE IS ONE
	PUSH	P,T2
	CAIN	T3,11		;IS THIS A TAB?
	JRST	ADJHP2		;YES, GO FIGURE OUT HOW BIG IT IS
	CAIN	T3,15		;CARRIAGE RETURN?
	JRST	ADJHP3		;SETS HPOS BACK TO START
	CAIE	T3,10		;BACKSPACE?
	JRST	T23PPJ		;NO, OTHER DON'T CHANGE HPOS
	PUSHJ	P,HPOS		;GET CURRENT POSITION
	JUMPE	T2,T23PPJ	;IF AT START OF LINE
	SOS	LDBHPS(U)	;ELSE DECREMENT POSITION BY ONE
	JRST	T23PPJ		;AND RETURN

;HERE FOR CARRIAGE RETURN

ADJHP3:	PUSHJ	P,SCNBOL	;BACK TO START OF LINE
	JRST	T23PPJ		;AND RETURN

;HERE FOR TAB

ADJHP2:	PUSHJ	P,HPOS		;CURRENT HORIZONTAL POSITION
	DPB	T2,POHPOS	;SAVE LOW 3 BITS FOR SIMULATION
	ANDI	T2,7		;ISOLATE (POSITION MOD 8)
	MOVN	T2,T2		; -(POSITION MOD 8)
	ADDI	T2,10		; 8-(POSITION MOD 8)
	ADDM	T2,LDBHPS(U)	;FIX HPOS COUNTER
	JRST	T23PPJ		;AND RETURN

;HERE FOR PRINTING CHARACTER

ADJHP1:	AOSA	LDBHPS(U)	;INCREMENT POSITION
T23PPJ:	POP	P,T2
	JRST	T3POPJ##
;HPOS -- SUBROUTINE TO FETCH THE CURRENT HORIZONTAL POSITION ON A LINE ;⊗ HPOS SCNBOL
;CALL
;	PUSHJ	P,HPOS
;	<ALWAYS RETURN HERE>
;EXIT WITH T2 = HORIZONTAL POSITION.  PRESERVES ALL OTHERS AC'S.

HPOS::	LDB	T2,LDPWID	;GET CARRIAGE WIDTH
	ADD	T2,LDBHPS(U)	;COMPUTE HORIZONTAL POSITION
	POPJ	P,		;AND RETURN IT


;ROUTINE TO SET A LINE BACK TO THE BEGINNING

SCNBOL:	PUSH	P,T2		;SAVE ALL AC'S
	LDB	T2,LDPWID	;GET WIDTH
	MOVNM	T2,LDBHPS(U)	;INITIAL VALUE OF HORIZONTAL POS COUNTER
	MOVEI	T2,0
	DPB	T2,POHPOS	;INITIAL LOW ORDER 3 BIT COUNTER
	JRST	T2POPJ##	;RESTORE T2 AND RETURN
;ROUTINE TO SUPPRESS BLANK LINES ;⊗ BLSUPI BLSUPO
IFN FTTBLK,<

BLSUPI:	PUSHJ	P,HPOS		;GET HORIZONTAL POSITION
	HRLI	T2,LPLSLF	;  (LPLSLF BIT IN LH)
	TRZE	T2,-1		;ANYTHING ON THIS LINE?
	ANDCAM	T2,LDBPAG(U)	;YES - CLEAR BIT TO ALLOW L.F.
	PUSH	P,T3		;SAVE CHARACTER
	ANDI	T3,177		;REDUCE TO 7-BIT ASCII
	CAIL	T3,12		;IS CHARACTER LF, VT, OR FF?
	CAILE	T3,14		; . . .
	JRST	T3POPJ##	;NO
	IORM	T2,LDBPAG(U)	;SET BIT TO SUPPRESS LF'S
	JRST	T3POPJ##	;BUT ALWAYS ECHO INPUT <CR><LF>S

BLSUPO:	PUSHJ	P,HPOS		;GET HORIZONTAL POSITION
	HRLI	T2,LPLSLF	;  (LPLSLF BIT IN LH)
	TRZE	T2,-1		;ANYTHING ON THIS LINE?
	ANDCAM	T2,LDBPAG(U)	;YES - CLEAR BIT TO ALLOW L.F.
	PUSH	P,T3		;SAVE CHARACTER
	ANDI	T3,177		;REDUCE TO 7-BIT ASCII
	CAIL	T3,12		;IS CHARACTER LF, VT, OR FF?
	CAILE	T3,14		; . . .
	JRST	T3POPJ##	;NO
	CAIN	T3,12		;YES-SUPPRESS LF?
	TDNN	T2,LDBPAG(U)
	SKIPA	T3,[12]		;NO-TURN VT OR FF INTO LF
	MOVEI	T3,0		;YES-TURN LF INTO NULL
	IORM	T2,LDBPAG(U)	;SET BIT TO SUPPRESS LF'S
	MOVE	T1,CHTABL(T3)	;GET BITS FOR NEW CHARACTER
	POP	P,T2		;RESTORE OLD CHARACTER
	TRNE	T2,200		;PARITY/VTM ECHO BIT?
	TRO	T3,200		;YES, ADD IT
	POPJ	P,
> ;IFN FTTBLK
;SUBROUTINE TO WAKE UP JOB IF IT IS IN TERMINAL INPUT WAIT. CALL WITH ;⊗ RCVWAK WAKJBR TTWAKE TTWAKI TTWAKO TTWAKB TTWAKX FULLCQ
;LINE SET UP. IT WILL SET DDB AND S AS NEEDED.

RCVWAK:
IFN FTCIMP,<			;[arpa]
	SKIPE	F,LDBIMP(U)	;[arpa] CROSSPATCHED TO IMP?
	  PJRST	TTIMPI		;[arpa] YES, HANDLE DIFFERENTLY
>				;[arpa]
	HRRZ	F,LDBDDB(U)	;GET ADDRESS OF ATTACHED DDB
	JUMPE	F,CPOPJ##	;IF NONE,SKIP THIS CODE
	PUSH	P,T1		;SAVE T1
	LDB	T1,PJOBN##	;GET JOB NUMBER OF TERMINAL OWNER
	MOVSI	S,TTILCE##	;IS JOB ENABLED FOR WAKE UP
	TDNE	S,JBTRTD##(T1)	;DURING A HIBERNATE
	JRST	WAKJB		;YES, GO WAKE JOB
WAKJBR:	POP	P,T1		;RESTORE T1

	MOVE	S,DEVIOS(F)	;GET STATUS OF TERMINAL FROM DDB
IFN FTPI,<TLZ S,IO>		;MAKE SURE BIT IS RIGHT
	TLNE	S,IOW		;JOB IN I/O WAIT FOR TERMINAL?
	TLNE	S,TTYOUW	;YES. FOR INPUT WAIT?
IFN FTPI,<JRST PSIIOD##>	;GENERATE PSI SO USER WILL KNOW I/O IS DONE
IFE FTPI,<POPJ P,0>		;NO--DON'T WAKE JOB.

TTWAKE::PUSH	P,T1		;SAVE VOLATILE AC'S
	PUSH	P,T2		; ..
	LDB	T1,PJOBN##	;IS JOB # IN DDB ZERO?
	JUMPE	T1,TTWAKX	;EXIT IF ZERO
	MOVE	S,DEVIOS(F)	;MAKE SURE S IS CORRECT
IFN FTPSCD,<
	MOVE	T1,LDBDCH(U)	;LINE CHARACTERISTICS
	JUMPL	S,TTWAKO	;OUTPUT?
TTWAKI:	TRNE	T1,LDRPTY	;INPUT. PTY?
	AOSA	%PISJB##	;YES
	  AOS	%TISJB##	;NO
	JRST	TTWAKB
TTWAKO:	TRNE	T1,LDRPTY	;OUTPUT. PTY?
	AOSA	%POSJB##	;YES
	  AOS	%TOSJB##	;NO
TTWAKB:>
	MOVEI	S,IOACT		;CLEAR I/O ACTIVE
	ANDCAB	S,DEVIOS(F)	;IN DDB FOR THIS JOB
	PUSHJ	P,STTIOD##	;CALL STTIOD FOR TERMINALS, PTYS
TTWAKX:	POP	P,T2		;RESTORE AC'S
	PJRST	TPOPJ##		;RETURN FROM RCVWAK

;ROUTINE TO SEE IF CHARACTER SPECIAL HANDLING SHOULD BE SUPPRESSED
;PRESERVES T1

FULLCQ:	PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  TLNN	U,LDLBKA+LDLFCS	;NO. DOES USER WANT ALL CHARACTERS?
	AOS	(P)		;NO. COMMAND OR NOT SMART USER
	POPJ	P,0		;SMART USER. NON-SKIP RETURN.
WAKJB:	PUSH	P,T2		;SAVE AC'S ;⊗ WAKJB HIBTTY HIBSET HIBTTL
	PUSH	P,T3
	MOVSI	T2,(JS.HIB)	;IS JOB SLEEPING
	TDNE	T2,JBTST2##(T1)	;OR HIBERNATING?
	PUSHJ	P,WAKJOB##	;HIBERNATING: WAKE THE JOB
	POP	P,T3		;RESTORE THE AC'S
	POP	P,T2
	JRST	WAKJBR		;RETURN TO NORMAL PROGRAM FLOW

;THE FOLLOWING ROUTINE IS CALLED BY THE HIBERNATE UUO TO
;PUT THE TERMINAL INTO CHARACTER MODE.  T1 IS PRESERVED.

HIBTTY::PUSH	P,T1		;SAVE T1
	PUSHJ	P,TTYFND	;FIND THIS JOB'S TTY
	JUMPE	U,TPOPJ##	;NO TERMINAL FOR THIS JOB
	MOVSI	T1,TTIACE##	;HIBERNATE IN CHARACTER MODE?
	TDNN	T1,JBTRTD##(J)
	JRST	HIBTTL		;NO, IT MUST BE LINE MODE
	PUSHJ	P,TTCCHK	;CHECK IF A CHARACTER IS ALREADY PRESENT
	  JRST	TPOPJ##		;NO LINE, ECHO STARTED
HIBSET:	MOVSI	T1,WAKEB##	;LINE OR CHARACTER PRESENT
	IORM	T1,JBTRTD##(J)	;DON'T HIBERNATE
	PJRST	TPOPJ##		;RESTORE T1 AND RETURN (TO UUOCON)
HIBTTL:	PUSHJ	P,TTLCHK	;CHECK FOR A LINE PRESENT
	  JRST	TPOPJ##		;NO LINE, ECHO STARTED
	JRST	HIBSET		;YES, DON'T GO TO SLEEP

;TABLE OF CONTROL CHARACTERS - LH=BITS, RH=DISP ADDR ON RCV INT ;⊗ CHBRK CHUAE CHFIL CHALT CHRIA CHCRET CHCNC CHDEL CHFILO CHCRE CHVPOS CHEPAR CHDELW CHPUNC CHXPIH CHSUSP CHXPIH CHSUSP CHSPO CHTABL

;DEFINITION OF BITS IN THIS TABLE
CHBRK==:1	;THIS IS A BREAK CHARACTER
CHUAE==:2	;THIS CHARACTER ECHOES AS ↑X
CHFIL==4	;THIS CHARACTER REQUIRES FILLERS AT SOME SPEEDS
CHALT==10	;THIS CHARACTER IS ONE OF THE THREE ALTMODES.
CHRIA==20	;THIS CHARACTER REQUIRES RCV INT LEVEL ACTION
CHCRET==40	;THIS IS A CARRIAGE RETURN (NEEDED FOR SETFLO)
CHCNC==100	;THIS IS CONTROL C
CHDEL==200	;THIS IS DELETE
CHFILO==400	;BIT ADDED FOR OUTPUT FILLER ROUTINE (NOT IN TABLE)
CHCRE==1000	;THIS CHARACTER GETS CRLF AFTER ITS ↑ X ECHO
CHVPOS==2000	;VERT. POSITIONING SIMULATED WITH FORM FEEDS
CHEPAR==:4000	;THIS BIT SET IF CHARACTER IS EVEN PARITY
CHDELW==10000	;THIS IS A CONTROL W
CHPUNC==20000	;THIS IS A PUNCTUATION CHARACTER
IFN FTCIMP,<	;[arpa]
CHXPIH==40000	;[arpa] SPECIAL HANDLING EVEN IF CROSSPATCHED TO IMP
CHSUSP==100000	;[arpa] SUPPRESS ECHO IF SPECIAL ACTION SUPPRESSED
>		;[arpa]
IFE FTCIMP,<	;[arpa]
CHXPIH==0	;DEFINED, BUT HAVE NO EFFECT
CHSUSP==0	;DITTO
>		;[arpa]
CHSPO==400000	;REQUIRES SPECIAL CHECKING ON OUTPUT.  MUST BE THE
		;SIGN BIT.

CHTABL:	XWD	CHSPO+CHRIA+CHEPAR+CHPUNC,RINUL			;↑@ NUL 000
IFN FTMIC,<
	XWD	CHSPO+CHRIA+CHUAE+CHPUNC,RICA			;↑A SOH 001
	XWD	CHSPO+CHRIA+CHUAE+CHPUNC,RICB			;↑B STX 002
>
IFE FTMIC,<
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑A SOH 001
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑B STX 002
>
	XWD	CHSPO+CHUAE+CHBRK+CHRIA+CHCRE+CHCNC+CHEPAR+CHPUNC,RICC	;↑C ETX 003
	XWD	CHSPO+CHUAE!CHRIA+CHPUNC,RICD			;↑D EOT 004
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑E ENQ 005
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑F ACK 006
	XWD	CHSPO+CHBRK+CHPUNC,0				;↑G BEL 007
;[arpa]	XWD	CHSPO+CHBRK+CHRIA+CHPUNC,RIBSP			;↑H BS 010
	XWD	CHSUSP+CHSPO+CHBRK+CHRIA+CHPUNC,RIBSP		;[arpa]↑H BS 010
	XWD	CHSPO+CHFIL+CHEPAR,0				;↑I HT  011
	XWD	CHSPO+CHFIL+CHBRK+CHEPAR+CHPUNC,0		;↑J LF  012
	XWD	CHSPO+CHFIL+CHBRK+CHVPOS+CHPUNC,0		;↑K VT  013
	XWD	CHSPO+CHFIL+CHBRK+CHVPOS+CHEPAR+CHPUNC,0	;↑L FF  014
;[arpa]	XWD	CHSPO+CHRIA+CHFIL+CHCRET+CHPUNC,RICM		;↑M CR  015
	XWD	chxpih+CHSPO+CHRIA+CHFIL+CHCRET+CHPUNC,RICM	;[arpa]↑M CR  015
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑N SO  016
	XWD	CHSPO+CHUAE+CHRIA+CHCRE+CHEPAR+CHPUNC,RICO	;↑O SI  017
IFN FTMIC,<
	XWD	CHSPO+CHRIA+CHUAE+CHPUNC,RICP			;↑P DLE 020
>
IFE FTMIC,<
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑P DLE 020
>
	XWD	CHSPO+CHUAE+CHFIL+CHRIA+CHEPAR+CHPUNC,RICQ	;↑Q XON 021
	XWD	CHSPO+CHUAE+CHFIL+CHRIA+CHBRK+CHEPAR+CHPUNC,RICR;↑R TAPE 022
	XWD	CHSPO+CHUAE+CHRIA+CHFIL+CHPUNC,RICS		;↑S XOFF 023
	XWD	CHSPO+CHUAE+CHFIL+CHRIA+CHBRK+CHEPAR+CHPUNC,RICT;↑T- NTAPE 024
;[arpa]	XWD	CHSPO+CHUAE+CHRIA+CHCRE+CHBRK+CHPUNC,RICU	;↑U NAK 025
	XWD	CHSUSP+CHSPO+CHUAE+CHRIA+CHCRE+CHBRK+CHPUNC,RICU ;[arpa]↑U NAK 025
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑V SYN 026
;[arpa]	XWD	CHSPO+CHUAE+CHRIA+CHEPAR+CHPUNC+CHDEL+CHDELW+CHBRK,RIDEL ;↑W ETB 027
	XWD	CHSUSP+CHSPO+CHUAE+CHRIA+CHEPAR+CHPUNC+CHDEL+CHDELW+CHBRK,RIDEL ;[arpa]↑W ETB 027
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑X CAN 030
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑Y EM  031
	XWD	CHSPO+CHUAE+CHBRK+CHCRE+CHPUNC,0		;↑Z SUB 032
;[arpa]	XWD	CHSPO+CHBRK+CHALT+CHRIA+CHEPAR+CHPUNC,RIALT	;↑[ ESC 033
	XWD	CHSUSP+CHSPO+CHBRK+CHALT+CHRIA+CHEPAR+CHPUNC,RIALT ;[arpa]↑[ ESC 033
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑\ FS  034
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑] GS  035
	XWD	CHSPO+CHUAE+CHEPAR+CHPUNC,0			;↑↑ RS  036
	XWD	CHSPO+CHUAE+CHPUNC,0				;↑← US  037

		0						;SPACE	040
	XWD	CHEPAR+CHPUNC,0					;!	041
	XWD	CHEPAR+CHPUNC,0					;"	042
	XWD	CHPUNC,0					;#	043
	XWD	CHEPAR+CHPUNC,0					;$	044
	XWD	CHPUNC,0					;%	045
	XWD	CHPUNC,0					;&	046
	XWD	CHEPAR+CHPUNC,0					;'	047
	XWD	CHEPAR+CHPUNC,0					;(	050
	XWD	CHPUNC,0					;)	051
	XWD	CHPUNC,0					;*	052
	XWD	CHEPAR+CHPUNC,0					;+	053
	XWD	CHPUNC,0					;,	054
	XWD	CHEPAR+CHPUNC,0					;-	055
	XWD	CHEPAR+CHPUNC,0					;.	056
	XWD	CHPUNC,0					;/	057
	XWD	CHEPAR,0					;0	060
		0						;1	061
		0						;2	062
	XWD	CHEPAR,0					;3	063
		0						;4	064
	XWD	CHEPAR,0					;5	065
	XWD	CHEPAR,0					;6	066
		0						;7	067
		0						;8	070
	XWD	CHEPAR,0					;9	071
	XWD	CHEPAR+CHPUNC,0					;:	072
	XWD	CHPUNC,0					;;	073
	XWD	CHEPAR+CHPUNC,0					;<	074
	XWD	CHPUNC,0					;=	075
	XWD	CHPUNC,0					;>	076
	XWD	CHEPAR+CHPUNC,0					;?	077
	XWD	CHPUNC,0					;@	100
	XWD	CHEPAR,0					;A	101
	XWD	CHEPAR,0					;B	102
		0						;C	103
	XWD	CHEPAR,0					;D	104
		0						;E	105
		0						;F	106
	XWD	CHEPAR,0					;G	107
	XWD	CHEPAR,0					;H	110
		0						;I	111
		0						;J	112
	XWD	CHEPAR,0					;K	113
		0						;L	114
	XWD	CHEPAR,0					;M	115
	XWD	CHEPAR,0					;N	116
		0						;O	117
	XWD	CHEPAR,0					;P	120
		0						;Q	121
		0						;R	122
	XWD	CHEPAR,0					;S	123
		0						;T	124
	XWD	CHEPAR,0					;U	125
	XWD	CHEPAR,0					;V	126
		0						;W	127
		0						;X	130
	XWD	CHEPAR,0					;Y	131
	XWD	CHEPAR,0					;Z	132
	XWD	CHPUNC,0					;[	133
	XWD	CHEPAR+CHPUNC,0					;/	134
	XWD	CHPUNC,0					;]	135
	XWD	CHPUNC,0					;↑	136
	XWD	CHEPAR+CHPUNC,0					;←	137

;THESE LETTERS ARE LOWER-CASE
	XWD	CHEPAR+CHPUNC,0					;`	140
		0						;a	141
		0						;b	142
	XWD	CHEPAR,0					;c	143
		0						;d	144
	XWD	CHEPAR,0					;e	145
	XWD	CHEPAR,0					;f	146
		0						;g	147
		0						;h	150
	XWD	CHEPAR,0					;i	151
	XWD	CHEPAR,0					;j	152
		0						;k	153
	XWD	CHEPAR,0					;l	154
		0						;m	155
		0						;n	156
	XWD	CHEPAR,0					;o	157
		0						;p	160
	XWD	CHEPAR,0					;q	161
	XWD	CHEPAR,0					;r	162
		0						;s	163
	XWD	CHEPAR,0					;t	164
		0						;u	165
		0						;v	166
	XWD	CHEPAR,0					;w	167
	XWD	CHEPAR,0					;x	170
		0						;y	171
		0						;z	172
	XWD	CHEPAR+CHPUNC,0					;{	173
	XWD	CHPUNC,0					;|	174

;THE 3 HIGH SPECIALS
	XWD	CHSPO+CHRIA+CHEPAR+CHALT+CHPUNC,RIALT		;}      175
	XWD	CHSPO+CHRIA+CHEPAR+CHALT+CHPUNC,RIALT		;~      176
;[arpa]	XWD	CHSPO+CHBRK+CHRIA+CHDEL+CHPUNC,RIDEL		;   DEL 177
	XWD	chsusp+CHSPO+CHBRK+CHRIA+CHDEL+CHPUNC,RIDEL	;[arpa] DEL 177
TTPWID:	POINT	8,TCRTAB(T1),7	;POINTER TO TERMINAL WIDTH ;⊗ TTPWID TTPPSZ TTPFLC TTPFRM TTPTAB TTPLCT TTPALT TTPDIS X1 X2 X3 X4 X5 CTCTAB TCRTAB
TTPPSZ:	POINT	6,TCRTAB(T1),13	;POINTER TO PAGE SIZE
TTPFLC:	POINT	2,TCRTAB(T1),35	;POINTER TO DEFAULT FILL CLASS
TTPFRM:	POINT	1,TCRTAB(T1),14	;ON IF TERMINAL HAS HARDWARE FORM FEEDS
TTPTAB:	POINT	1,TCRTAB(T1),15	;ON IF TERMINAL HAS HARDWARE TABS
TTPLCT:	POINT	1,TCRTAB(T1),16	;ON IF TERMINAL DOESN'T HAVE LOWER CASE CHARACTERS
TTPALT:	POINT	1,TCRTAB(T1),17	;ON IF NO ALTMODE CONVERSION IS REQUIRED
TTPDIS:	POINT	1,TCRTAB(T1),18	;ON IF "DISPLAY" TERMINAL (E.G., FOR DDT)

DEFINE	TERMCR(NAME,WIDTH,LENGTH,FF$,TAB$,LC$,ALT$,DIS$,FILL,BPERAS,BPRUBO),<
X1==0
IFIDN <FF$><FF>,<X1==1>
X2==0
IFIDN <TAB$><TAB>,<X2==1>
X3==1
IFIDN <LC$><LC>,<X3==0>
X4==1
IFIDN <ALT$><ALT>,<X4==0>
X5==0
IFIDN <DIS$><DIS>,<X5==1>
IFNDEF TT'NAME,<TT'NAME:>BYTE	(8)WIDTH(6)LENGTH(1)X1(1)X2(1)X3(1)X4(1)X5(15)0(2)FILL
	XWD	BPERAS,BPRUBO	;<CR> EOL,,B.S. SPACE B.S.
>
CTCTAB:			;CUSTOMER TERMINAL CHARACTERISTICS GO HERE
TERMCR	LA34,↑D132,0,NOFF,TAB,LC,NOALT,NODIS,0,0,0
TERMCR	HP2621,↑D80,↑D24,FF,NOTAB,LC,NOALT,DIS,0,HP26EP,VTXXBP	;[hp2621]
TERMCR	DM1500,↑D80,↑D24,FF,TAB,LC,NOALT,DIS,0,DM15EP,VTXXBP	;[dm1500]
TCRTAB:			;SEE TTTWDT IN COMCON
TERMCR	TTY,↑D72,0,NOFF,NOTAB,NOLC,ALT,NODIS,1,0,0
TERMCR	VT05,↑D72,↑D20,NOFF,TAB,NOLC,NOALT,DIS,2,VT06EP,VTXXBP
TERMCR	VT06,↑D72,↑D25,NOFF,NOTAB,NOLC,NOALT,DIS,1,VT06EP,VT06BP
TERMCR	VT50,↑D80,↑D12,NOFF,TAB,NOLC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	VT52,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	VT61,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	DAS21,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,VTXXEP,VTXXBP
TERMCR	VT100,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,V100EP,VTXXBP
TERMCR	TY33,↑D72,0,NOFF,NOTAB,NOLC,ALT,NODIS,1,0,0
TERMCR	TY35,↑D72,0,FF,TAB,NOLC,ALT,NODIS,1,0,0
TERMCR	LA30,↑D72,0,NOFF,NOTAB,NOLC,NOALT,NODIS,1,0,0
TERMCR	LA36,↑D132,0,NOFF,NOTAB,LC,NOALT,NODIS,0,0,0
TERMCR	2741,↑D128,0,NOFF,NOTAB,LC,NOALT,NODIS,3,0,0
TERMCR	LA38,↑D132,0,NOFF,TAB,LC,NOALT,NODIS,0,0,0
TERMCR	LA120,↑D132,0,FF,TAB,LC,NOALT,NODIS,0,0,0
TERMCR  VT125,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,V100EP,VTXXBP
TERMCR  VK100,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,V100EP,VTXXBP
TERMCR  VT101,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,V100EP,VTXXBP
TERMCR  VT102,↑D80,↑D24,NOFF,TAB,LC,NOALT,DIS,0,V100EP,VTXXBP
;ROUTINE TO CHECK FOR A SPECIAL CHARACTER AND SET T1 TO ITS DESCRIPTOR ;⊗ SPCHEK PEVEN8
;ENTER WITH T3 SET UP
;SKIPS IF CHAR IS 0-37 OR 175-177
;IGNORES AND DOES NOT RETURN PARITY BIT (CHEPAR)


SPCHEK::MOVE	T1,T3		;COPY CHAR
	ANDI	T1,177		;CLEAR PARITY
	TRNE	T3,400
	TDZA	T1,T1
	MOVE	T1,CHTABL(T1)	;GET TABLE ENTRY
	TLZ	T1,CHEPAR+CHPUNC;CLEAR PARITY AND PUNCTUATION BIT
	SKIPE	T1		;SPECIAL?
	AOS	(P)		;YES--SKIP
	POPJ	P,		;RETURN


;SUBROUTINE TO GET EVEN PARITY USING CHEPAR BIT OF CHTABL
;CALLED FROM SCNSER,PTPSER AND IN ONCE

;CALLING SEQUENCE:  PUSHJ	P,PEVEN8

;ON ENTRY, T3 CONTAINS A CHARACTER IN BITS 28 TO 35,
; BITS 0 TO 27 ARE IGNORED

;ON EXIT, BIT 28 IS CHANGED IF NECESSARY SUCH THAT THE PARITY
; OF BITS 28 TO 35 IS EVEN, AND BITS
; 0 TO 27 ARE ALL 0

PEVEN8::ANDI	T3,177		;CLEAR TO 7 BITS FOR INDEX
	PUSH	P,T1		;SAVE T1
	MOVE	T1,CHTABL(T3)	;GET CHARACTER TABLE ENTRY
	TLNN	T1,CHEPAR	;ALREADY EVEN
	TRO	T3,200		;WAS NOT, PUT IN PARITY BIT
	JRST	TPOPJ		;RESTORE T1 AND RETURN
	SUBTTL	CHUNK HANDLERS ;⊗ NEWCKO NWCKO1 NEWCKI

;The routines NEWCKI and NEWCKO are provided only to support the
;macros LDCHK, LDCHKR, and STCHK.  They should not be called directly
;because they depend on the instruction following the call to be a 
;byte instruction that references the byte pointer into the chunk
;string.

;NEWCKO -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN PUTTING CHARACTERS
;	  INTO THE TERMINAL BUFFER CHUNKS.

NEWCKO::PUSH	P,@(P)		;SAVE ADDRESS OF THE BYTE INSTRUCTION
	HRRZ	T2,@(P)		;ADDRESS OF LAST BYTE IN CHUNK
	MOVEI	T2,CK.BTH##(T2)	;ADDRESS OF CURRENT CHUNK HEADER
	HRRZ	T1,(T2)		;IS THERE A CHUNK THERE YET?
	JUMPN	T1,[EXCH T1,T3
		    PUSHJ P,RCCCHK
		    EXCH T1,T3
		    JRST NWCKO1]
	PUSHJ	P,GETCHK	;ALLOCATE A CHUNK FROM FREE LIST
	HRLZM	T2,(T1)		;BACK POINTER TO EXISTING LIST
	HRRM	T1,(T2)		;FORWARD POINTER TO NEW CHUNK
NWCKO1:	ADD	T1,[POINT 9,1]	;MAKE A BYTE POINTER
	MOVEM	T1,@(P)		;STORE IN STRING POINTER
	SUB	P,[1,,1]	;PRUNE PUSH DOWN LIST
	POPJ	P,		;AND RETURN

;NEWCKI -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS
;	   OUT OF THE TERMINAL CHUNKS.  USES T2 AND T3.

NEWCKI::PUSH	P,@(P)		;SAVE ADDRESS OF THE BYTE INSTRUCTION
	HRRZ	T3,@(P)		;ADDRESS OF LAST BYTE
	MOVEI	T1,CK.BTH##(T3)	;ADDRESS OF CHUNK HEADER
	HRRZ	T3,CK.BTH##(T3)	;FORWARD CHUNK POINTER
	PUSHJ	P,RCCCHK
	HRRZS	(T3)		;CLEAR BACK POINTER
	PUSHJ	P,FRECHK	;FREE UP THE STALE CHUNK
	ADD	T3,[POINT 9,1]	;MAKE FORWARD POINTER INTO A BYTE PTR
	MOVEM	T3,@(P)		;STORE IT BACK IN POINTER WORD
	SUB	P,[1,,1]	;PRUNE PUSH DOWN LIST
	POPJ	P,		;AND RETURN
;NEWCKS -- ROUTINE TO ADVANCE TO THE NEXT CHUNK WHEN TAKING CHARACTERS ;⊗ NEWCKS CL0STP RCCCHK
;	   OUT OF THE TERMINAL CHUNKS.  DIFFERS FROM NEWCKI IN THAT THE
;	   STALE CHUNKS ARE NOT DELETED.

NEWCKS:	PUSH	P,@(P)		;SAVE ADDRESS OF THE BYTE INSTRUCTION
	HRRZ	T3,@(P)		;ADDRESS OF LAST BYTE
	MOVEI	T1,CK.BTH##(T3)	;ADDRESS OF CHUNK HEADER
	HRRZ	T3,CK.BTH##(T3)	;FORWARD CHUNK POINTER
	PUSHJ	P,RCCCHK
	ADD	T3,[POINT 9,1]	;MAKE FORWARD POINTER INTO A BYTE PTR
	MOVEM	T3,@(P)		;STORE IT BACK IN POINTER WORD
	SUB	P,[1,,1]	;PRUNE PUSH DOWN LIST
	POPJ	P,		;AND RETURN

CL0STP:	STOPCD .,STOP,CL0,	;++CHUNK LINKS TO ZERO

RCCCHK:	PUSH	P,T3		;SAVE ALL
	CAML	T3,TTBASE	;IF TOO LARGE
	CAMLE	T3,RCCMAX##	; OR TOO SMALL
	PUSHJ	P,RCCSTP	;
	ANDI	T3,CK.BDY	;JUST OFFSET WITHIN CHUNK
	CAIE	T3,1		;MUST BE ONE
	PUSHJ	P,RCCSTP	;ISN'T, DIE
	HLRZ	T3,@(P)		;ADDRESS OF PREDECESSOR
	HRRZ	T3,(T3)		; SHOULD POINT TO US
	CAME	T3,(P)		;...
	PUSHJ	P,RCCSTP	;DOESN'T, CHUNKS AE MESSED UP
	JRST	T3POPJ##	;RESTORE T3 AND RETURN
	SUBTTL	CHUNK HANDLERS -- ALLOCATION AND DEALLOCATION ;⊗ GETCKZ GETCHK FRECHK

;FRECHK and GETCHK are called to return and fetch chunks from the
;SCNSER chunk free chain.  The chain is maintained in first-in first-out
;order in order to preserve as much information for crash analysis as
;possible.  The oldest chunk is pointed to by TTFTAK, while the youngest
;is pointed to by TTFPUT.  To aid in reconstruction of the events
;leading to a crash, the left half of each chunk header contains the LDB
;address of the line that last used it.

GETCKZ:	PUSHJ	P,GETCHK	;GET A FREE CHUNK
	SETZM	(T1)		;ZERO THE LINK WORD
	POPJ	P,		; AND RETURN

GETCHK:	SKIPN	T1,TTFTAK	;CHECK THE FREE LIST
	STOPCD	.,STOP,FLE,	;++FREE LIST EMPTY
	PUSH	P,T2		;SAVE T2
	HRRZ	T2,(T1)		;TO NEXT CHUNK
	MOVEM	T2,TTFTAK	;STORE POINTER TO NEW FIRST CHUNK
	SOS	TTFREN##	;COUNT DOWN NUMBER OF FREE CHUNKS
	JUMPN	T2,T2POPJ##	;IF NOT LAST CHUNK, RETURN
	MOVEI	T2,TTFTAK	;MAKE TTFPUT POINT AT TTFTAK SO
	MOVEM	T2,TTFPUT	; FRECHK WILL RELINK THE POINTERS CORRECTLY
	JRST	T2POPJ##	; AND RETURN

FRECHK:	HRLZM	U,(T1)		;MARK LINE NUMBER IN CHUNK
	HRRM	T1,@TTFPUT	;STORE CHUNK AT END
	HRRZM	T1,TTFPUT	;POINT TO NEW ENTRY.
	AOS	TTFREN##	;COUNT UP NUMBER OF CHUNKS
	POPJ	P,
	SUBTTL	CHUNK HANDLERS -- CLEAR BUFFERS ;⊗ TSETBI TSETI2 TSETBO TSETB1 TSETB2 RCCSTP

;ROUTINES TO CLEAR INPUT AND OUTPUT BUFFERS

TSETBI::TRNN	U,-1
	STOPCD	.,STOP,LNS,	;++LINE NOT SETUP
	PUSHJ	P,STOPCM
	SCNOFF
TSETI2:	SETZM	LDBTIC(U)	;CLEAR COUNTS
	SETZM	LDBECC(U)	;OF INPUT CHARACTERS
	MOVE	T1,LDBTIT(U)	;MOVE PUTTERS BACK TO TAKER
	MOVEM	T1,LDBTIP(U)
	MOVEM	T1,LDBECT(U)	;NO ECHOING EITHER
	SETZM	LDBBKU(U)
	SETZM	LDBBKC(U)	; ..
	MOVEI	T1,L2RECS	;CLEAR BIT IN LDB WHICH
	ANDCAM	T1,LDBBY2(U)	; MIGHT CAUSE A LINE TO BE SKIPPED
	SCNON
	PJRST	CHKXON		;CHECK IF AN XON MUST BE SENT OUT AND EXIT

TSETBO::
IFN FTTPAG,<
	MOVSI	T1,LDLSTP+LDLSSO;CLEAR OUTPUT STOP BIT
	ANDCAM	T1,LDBDCH(U)	;OUTPUT CAN NOW HAPPEN AGAIN
>
	SCNOFF			;NO PI'S HERE
IFN FTMIC&FTMLOG,<
	SKIPE	LDBLOT(U)
	JRST	MICLGC
> ;END OF FTMLOG CONDITIONAL
	SETZM	LDBTOC(U)	;NO OUTPUT CHARACTERS LEFT
	MOVE	T1,LDBTOT(U)	;PUT PUTTER BACK AT TAKER
	MOVEM	T1,LDBTOP(U)	; ..
	MOVEI	T3,-1(T1)	;ADDRESS PART OF POINTER
	TRZ	T3,CK.BDY	;ADDRESS OF CHUNK HEADER MINUS ONE.
	HRRZ	T1,1(T3)	;ADDRESS OF FIRST CHUNK IN CHAIN TO DELETE
	JUMPE	T1,TSETB2	;IF NULL CHAIN
	SETZM	1(T3)		;CLEAR POINTER TO CHAIN BEFORE DELETION
TSETB1:	HRRZ	T3,(T1)		;POINTER TO CHUNK FOLLOWING CURRENT
	PUSHJ	P,FRECHK	;DELETE ONE CHUNK
	MOVEI	T1,(T3)		;NEXT CHUNK ON CHAIN
	JUMPN	T1,TSETB1	;LOOP TO END OF CHAIN
TSETB2:
	SCNON			;ALL'S CLEAR NOW
	MOVEI	T3,3		;ISR CODE FOR CHAR GOBBLER
	MOVEI	T1,ISRREM	;SPECIAL ISR ENTRY FOR REMOTES
	PJRST	@LDBISR(U)	;SEND MESSAGE TO CLEAR OUTPUT BUFFER IN REMOTE

RCCSTP:	STOPCD	.,STOP,RCC,	;++RANGE CHECKED CHUNK
	SUBTTL	UUO LEVEL ROUTINES FOR BUFFERED I/O ;⊗ SCNDSP

;DISPATCH TABLE FOR UUO'S AND INITIALIZATION

	JRST	ECOD2##		;NO DEVOP FUNCTIONS
	JRST	REGSIZ##	;BUFFER SIZE CAN BE GOTTEN FROM DDB
	JRST	TTYINI##(P2)	;INITIALIZATION (140 RESTART)
	JRST	CPOPJ1##	;HUNG DEVICE (NEVER USED)
SCNDSP::JRST	TTYREL		;RELEASE
	JRST	OUT##		;CLOSE OUTPUT
	JRST	TTYOUT		;TTY OUTPUT UUO
;	JRST	TTYIN		;TTY INPUT UUO
;FALL INTO TTYIN
;INPUT UUO PROCESSOR - CALLED FROM UUOCON ON INPUT UUO, DDB SET UP ;⊗ TTYIN TTYINA TTYIN0 TTYIN5


TTYIN:	PUSHJ	P,SAVE3##	;SAVE P1-P3
	PUSHJ	P,CKATTI	;MAKE SURE ATTACHED. SET S.
	MOVEI	T1,DEPAIO	;IS THIS TERMINAL IN ASYNC INPUT
	TDNN	T1,DEVAIO(F)	; MODE?
	JRST	TTYINA		;NO--FORGE AHEAD
	PUSHJ	P,TTICHK	;IS THERE ANY INPUT AVAILABLE?
	  POPJ	P,0		;NO--RETURN NOW
TTYINA:	TRNN	S,I		;IMAGE MODE?
	JRST	TTYIN0		;NO. SKIP SETUP STUFF
	TRNN	S,IODERR	;EOF DUE TO ↑C ON UNATTACHED LINE?
	TLNE	S,FRCEND	;CLOCK ROUTINE WANT IT FINISHED?
	JRST	TTYIN9		;YES. GO DO SO.
	MOVE	T1,DEVMOD(F)	;IS THIS GUY ALLOWED IMAGE MODE INPUT?
	TRNN	T1,ASSCON	;I.E., HE HAS TERMINAL ASSIGNED?
	JRST	TTYINE		;NO. ERROR BIT TO USER.
	MOVSI	T1,LDLIMI	;YES. SET IMAGE INPUT IN LINE DATA
	IORM	T1,LDBDCH(U)	; ..
	PUSHJ	P,SETCHP	;MAKE SURE THAT THE FRONT END KNOWS
TTYIN0:	PUSHJ	P,TWAITI	;BECOME ATTACHED, WAIT FOR INPUT
				; OR FULL BUFFER CONDITION
	TLNE	S,FRCEND	;DID WE TIME OUT AT CLOCK
	JRST	TTYIN9		;LEVEL WHILE WAITING ?
TTYIN5:	HRRZ	T1,DEVIAD(F)	;PREPARE AND ADDR CHECK THE
	PUSHJ	P,BUFCLR##	; USER'S BUFFER
	  JRST ADRERR##		;OUT OF BOUNDS. STOP JOB.
	HRRZ	P1,DEVIAD(F)	;USER VIRTUAL ADDRESS OF BUFFER
	EXCTUX	<LDB P2,[POINT 17,@P1,17]>  ;SIZE OF BUFFER (DATA + 1)
	SUBI	P2,1		;LESS THE .BFCNT WORD
	HRRZ	U,DDBLDB(F)	;RESTORE LINE, CLOBBERED IN UUOCON
	PUSHJ	P,SRLPTR	;SETUP BYTE COUNT AND POINTER
	PUSH	P,P2		;SAVE BYTE COUNT
				;FALL INTO MAIN PART OF ROUTINE
TTYIN1:	PUSHJ	P,TYICC		;GET A CHARACTER ;⊗ TTYIN1 TTYIN2 TTYIN3 TTYINC TTYIN8 TTYINX TTYINE TTYIN9
	  JRST TTYIN3		; END OF BUFFER.
	MOVE	P3,T3		;COPY CHARACTER
	ANDI	P3,377		;STRIP IMAGE BIT
	EXCTUU	<IDPB P3,P1>	;AND STORE IN USER AREA
	TRNN	S,I!PIMMOD	;SKIP IF IMAGE MODE OF SOME SORT
	JRST	TTYIN2		;NO, ASCII MODE
	SOJG	P2,TTYIN1	;YES, JUST FILL BUFFER
	JRST	TTYIN3		;BUFFER FULL, GIVE IT TO THE USER

TTYIN2:	TLNN	T1,CHBRK	;A BREAK?
	SOJG	P2,TTYIN1	;NO. LOOP FOR MORE, IF ROOM.
	MOVSI	S,IOEND		;COUNTED OUT, OR BREAK.
	MOVE	T1,DEVIOS(F)	;GET USER MODE BITS
	TRZ	T3,200		;STRIP OFF PARITY, NOT IMAGE.
	TRNN	T1,IOSTEC	;TRUTH-IN-ECHOING MODE AND
	CAIE	T3,"Z"-100	;END OF FILE CHARACTER?
	MOVEI	S,0		;NO. NOT EOF.
	IORB	S,DEVIOS(F)	;STORE IN DDB S WORD
TTYIN3:	POP	P,T1		;GET BACK ORIGINAL MAX BYTE COUNT
	TRNN	S,PIMMOD	;BYTE COUNT IF PIM
	SKIPA	P2,DEVIAD(F)	;NOT PIM - BUFFER PTR IN P2
	SKIPA			;PIM - DON'T DESTROY BYTE COUNT
	JRST	TTYINC		;NOT PIM-WORD COUNT
	MOVN	P1,P2		;COUNT OF BYTES LEFT
	ADD	P1,T1		;FROM MAX = COUNT OF BYTES DEPOSITED
	SKIPA	P2,DEVIAD(F)	;ALREADY HAVE COUNT IN P1
TTYINC:	SUBI	P1,1(P2)	;COMPUTE WORD COUNT FOR UUOCON
	EXCTUU	<HRRM P1,1(P2)>	;STORE WITH DATA IN RING
	PUSHJ	P,ADVBFF##	;ON TO NEXT BUFFER
	  JRST	TTYIN8		;NO MORE BUFFERS AVAILABLE
	TRNE	S,I!PIMMOD	;IMAGE MODE?
	SKIPG	LDBTIC(U)	;AND MORE CHARACTERS TO READ?
	JRST	TTYIN8		;NO - ASCII, ONLY PASS ONE LINE AT A TIME
	JRST	TTYIN5		;YES. GO PASS SOME MORE

TTYIN8:	MOVSI	S,IOFST		;SET VIRGIN BUFFER BIT
TTYINX:	IORB	S,DEVIOS(F)	;IN DEV S WORD IN DDB
	HRRZ	U,DDBLDB(F)
	JUMPE	U,CPOPJ##
	PJRST	NOCTRO		;CLEAR CONTROL O. END OF UUO

;HERE IF ATTEMPT TO PUT UNASSIGNED TERMINAL IN IMAGE INPUT STATE

TTYINE:	MOVEI	S,IOIMPM
	JRST	TTYINX		; AND RETURN

TTYIN9:	MOVSI	S,IOEND		;SET END OF FILE BIT IN S
	JRST	TTYINX
;OUTPUT UUO CALLS HERE ;⊗ TTYOUT TTOUT0 TTOUT1

;CALLED ON OUTPUT OR OUTPUT CLOSE, FROM UUOCON, WITH DDB SET UP.


TTYOUT:	PUSHJ	P,SAVE2##	;SAVE P1-P2
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
	TRNE	S,IODERR	;↑C TYPED AT TTYNNN
	JRST	TTOUT3		;YES, RETURN
	PUSHJ	P,CKATOU	;FIRST, MAKE SURE THERE'S A
				; PHYSICAL LINE ATTACHED TO JOB, AT USER LEVEL
	TRNN	S,I		;UNLESS IMAGE MODE,
	PUSHJ	P,CLRIMI	;CLEAR IMAGE INPUT STATE
	MOVSI	S,IOBEG		;IS THIS THE FIRST BUFFER AFTER INIT?
	TDNN	S,DEVIOS(F)	;CHECK DDB
	JRST	TTOUT1		;NO.
	ANDCAM	S,DEVIOS(F)	;YES. CLEAR BEG BIT,
	PUSHJ	P,NOCTRO	; AND CONTROL O
TTOUT0:	SETZM	DEVSTS(F)	;CLEAR OLD PARTIAL BYTE POINTER IF ANY

;OUTPUT A BUFFER OF TEXT. AT THIS POINT WE COULD CHECK FOR ↑O IN EFFECT
;AND JUST EAT THE BUFFER, BUT WE DON'T WANT ↑O TO BE TOO FAST . . .

TTOUT1:	MOVE	S,[IO!IOFST,,IOACT]	;MARK START OF NEW OUTPUT
	IORB	S,DEVIOS(F)	;IN DEVICE DATA BLOCK
	HRRZ	P1,DEVOAD(F)	;USER VIRTUAL ADDRESS OF OUTPUT BUFFER
	HRRZ	T1,P1		;CHECK ADDRESSES OF OUTPUT BLOCK
	PUSHJ	P,BRNGE##	;MAKE SURE BUFFER IS ADDRESSABLE
	EXCTUX	<HRRZ P2,1(P1)>	;SIZE OF DATA AREA (WORDS) TO BE OUTPUT
	JUMPE	P2,TTOUT6	;SKIP THIS BUFFER IF EMPTY
	EXCTUX	<LDB T1,[POINT 17,@P1,17]>  ;GET TOTAL BUFFER SIZE
	CAML	P2,T1		;DATA CONTAINED WITHIN BUFFER?
	JRST	TTYINE		;NO, USER BLEW IT
				; (IT ALSO MIGHT IME US!)
	PUSHJ	P,SRLPTR	;GET BYTE COUNT AND POINTER
	SKIPN	DEVSTS(F)	;OUTPUT PENDING?
	JRST	TTOUT2		;NO, NEW BUFFER
	MOVE	P1,DEVSTS(F)	;YES, GET LAST OUTPUT POINTER
	LDB	P2,BYTCNT	;AND REMAINING BYTE COUNT
				; AND FINISH (MAYBE) OUTPUTTING THE BUFFER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ TTOUT2 TTOUT4 TTOUT5 TTOUT6 TTOUT3 TTOUT7 TTOUT8

;LOOP OUTPUTTING CHARACTER FROM THE USER BUFFER

TTOUT2:	PUSHJ	P,CKROOM	;SEE IF WE SHOULD CALL TYO
	  JRST	TTOUT7		;IO WAIT WOULD HAPPEN
	MOVE	T3,P1		;COPY BYTE POINTER
	EXCTUX	<ILDB T3,T3>	;INCREMENT THIS COPY, GET USER'S CHAR
	ANDI	T3,377		;KEEP JUST THE CHARACTER
	TRNE	S,I!PIMMOD	;SEE IF IMAGE MODE OR PIM
	TROA	T3,400		;YES.  SET BIT FOR SUPPRESSING FILLERS
	JUMPE	T3,TTOUT4	;DON'T OUTPUT NULLS
	MOVEI	T1,DEPAIO	;IF DOING ASYNCHRONOUS I/O,
	TDNE	T1,DEVAIO(F)	; TELL TYO NOT TO BLOCK SINCE
	TLO	T3,(1B0)	; WE MAY BE HERE FORM TTMORE
	TRNE	S,IODERR	;↑C TYPED ON TTYNNN
	JRST	TTOUT3		;YES, RETURN
	PUSHJ	P,TYO9W		;OUTPUT THIS CHARACTER (WAIT IF NEEDED)
	JUMPL	T3,TTOUT7
TTOUT4:	IBP	P1
TTOUT5:	SOJG	P2,TTOUT2	;COUNT USER'S ITEMS.
TTOUT6:	PUSHJ	P,ADVBFE##	;ADVANCE HIS BUFFERS
	  JRST	TTOUT3		;JUST SINGLE BUFFER FOR NOW
	MOVEI	T1,DEPAIO	;NON-BLOCKING I/O BIT
	TDNE	T1,DEVAIO(F)	;DOING NON-BLOCKING I/O
	JRST	TTOUT0		;YES, START THE NEXT BUFFER OUT
TTOUT3:	SETZM	DEVSTS(F)
	MOVEI	S,IOACT		;CLEAR ACTIVE BIT.
	ANDCAB	S,DEVIOS(F)	;IN DEVICE DATA BLOCK FOR THE JOB
	POPJ	P,0		;END OF UUO. RETURN TO USER

TTOUT7:	MOVEM	P1,DEVSTS(F)	;SAVE THE INTERRUPTED BYTE POINTER
	DPB	P2,BYTCNT	; AND ITS COUNTER
TTOUT8:	MOVEI	T1,JS.NTO	;SET THE MAGIC
	IORM	T1,JBTSTS##(J)	; BIT IN JBTSTS
	MOVEI	S,IOACT		;CLEAR I/O ACTIVE BIT
	ANDCAB	S,DEVIOS(F)	;..
	POPJ	P,0		;RETURN
TTMORE::PUSHJ	P,SAVE2##	;SAVE P1-P2 ;⊗ TTMORE MORE10 MORE20 MORE30 MORE40 MOR405 MORE41
	MOVEI	F,SCNDDB	;FIRST DDB
	MOVEI	P2,JS.NTO	;FLAG RESET
	MOVE	T1,.CPPC##	;GET THE CURRENT PC
	TLNE	T1,USRMOD	;IN USER MODE?
	MOVEM	T1,.JDAT+JOBPD1##	;YES--MAKE SURE JOBPD1 IS RIGHT
MORE10:	LDB	T1,PJOBN##	;GET OWNER
	CAIN	T1,(J)		;IS IT THIS JOB?
	SKIPN	DEVSTS(F)	;IS OUTPUT WAITING?
	JRST	MORE20		;NO, TRY NEXT DDB
	MOVEI	T1,DEPAIO
	TDNN	T1,DEVAIO(F)	;NON-BLOCKING I/O ON THIS TERMINAL?
	JRST	MORE20		;NO, LOOK AT OTHER TERMINALS
	PUSHJ	P,MORE30	;GO TRY OUTPUT
	MOVEI	P2,0		;FLAG ONE ACTIVE
MORE20:	HLRZ	F,DEVSER(F)	;PICK UP NEXT DDB
	MOVSI	T1,DVTTY	;IS THIS A TTY?
	TDNE	T1,DEVMOD(F)	; ..
	JUMPN	F,MORE10	;YES--LOOK AT IT TOO
	ANDCAM	P2,JBTSTS##(J)	;CLEAR THE STATUS
	POPJ	P,0		;RETURN
MORE30:	HRRZ	U,DDBLDB(F)	;GET ADDRESS OF LDB
	JUMPE	U,CPOPJ##	;PUNT IF DETACHED
	MOVE	S,DEVIOS(F)	;SET UP S FOR TYO
	LDB	P1,BYTCNT	;GET THE BYTE COUNT
	JUMPE	P1,MORE41	;IF BYTE COUNT=0 AND DEVSTS NON-0, BUFFER WASN'T ADVANCED
				; BECAUSE WHAT DEVOAD POINTED TO WAS PAGED OUT

MORE40:	PUSHJ	P,CKROOM	;ROOM FOR MORE DATA?
	  JRST	[DPB P1,BYTCNT	;NO--SAVE BYTE COUNT
		 POPJ P,0]	;RETURN
	MOVE	T1,DEVSTS(F)	;GET POINTER
	IBP	T1		;UPDATE POINTER
	MOVE	T3,T1		;COPY BYTE POINTER
	TLZ	T1,-1		;CLEAR JUNK
	PUSHJ	P,IADRCK##	;MAKE SURE ITS LEGAL AND IN CORE
	  JRST	MORE50
	EXCTUX	<LDB T3,T3>	;GET NEXT BYTE
	TRNE	S,I!PIMMOD	;IF IMAGE OR PIM
	TROA	T3,400		;FLAG IT
	JUMPE	T3,MOR405	;SKIP CALL IF NO CHARACTER
	TLO	T3,(1B0)	;DON'T BLOCK IN TYO
	PUSHJ	P,TYO9W		;TYPE IT
	JUMPGE	T3,MOR405	;PROCEED IF CHAR OUTPUT
	DPB	P1,BYTCNT	;ELSE REMEMBER WHERE
	JRST	TTOUT8		;WE WERE & RETURN
MOR405:	IBP	DEVSTS(F)	;INCREMENT PRIME COPY
	SOJG	P1,MORE40	;DO THE NEXT BYTE
MORE41:	HRRZ	T1,DEVOAD(F)	;BUF APR
	SOS	T2,T1		;WORD-1
	ADDI	T2,3		;THRU WORD1
	PUSHJ	P,ZRNGE##	;IN CORE?
	  JRST	MORE50		;NO

IFN FTPI,<
	TLO	S,IO		;FORCE FLAG TO OUTPUT
	PUSHJ	P,PSIIOD##
>
	JRST	TTOUT6		;ALL DONE
MORE50:	DPB	P1,BYTCNT	;SAVE BYTE COUNT ;⊗ MORE50 CKROOM
	MOVE	T3,.CPPC##	;JOB'S PC
	TLNN	T3,USRMOD	;IN USER MODE?
	POPJ	P,		;NO, TRY AGAIN LATER
	MOVE	T3,[EXP IC.UOU+TTYFLT##]
	MOVEM	T3,.CPPC##	;GO TO TTYFLT
	MOVEM	T1,.UPMP+.UPUPF	;STORE FAULT ADDRESS
	POPJ	P,


CKROOM:	MOVEI	T1,DEPAIO	;IF THIS JOB IS NOT USING
	TDNN	T1,DEVAIO(F)	; ASYNCHRONOUS I/O THEN
	JRST	CPOPJ1##	; JUST GIVE THE SKIP RETURN
	SKIPLE	T1,TTFREN##	;GET THE FREE CHUNK COUNT
	CAIG	T1,5		;ENOUGH ROOM?
	POPJ	P,0		;NO--QUIT NOW
	MOVE	T1,LDBTOC(U)	;GET OUTPUT BYTE COUNT
	ADDI	T1,↑D25		;REDUCE ODDS OF LOSSAGE
	CAMG	T1,TIWRNN	;TOO MUCH STUFF?
	AOS	(P)		;NO--CALL TYO
	POPJ	P,0		;RETURN
	SUBTTL	DDT MODE CALLI'S ;⊗ DDTIN DDTINL DDTINX DDTOUT

;INPUT TO DDT	- CALL AC,[SIXBIT /DDTIN/]  WHERE AC/ ADDR
;ADDR GETS UP TO 21 WORDS OF ASCIZ, BREAKING ON ANY CHARACTER

DDTIN::	PUSHJ	P,SAVE3##	;SAVE P1-P3 (TYICC KRUMPS P3)
	PUSHJ	P,TTYFNU	;SET LINE AND DDB FOR THIS TTY
	PUSHJ	P,CKATTI	;MAKE SURE TERMINAL ATTACHED
	PUSHJ	P,GETWDU##	;DO ADDRESS CHECKING FIRST
	HRRZS	T1
	PUSHJ	P,IADRCK##	; ..
	  JRST	ADRERR##	;NO GOOD
	ADDI	T1,21		;CHECK END OF AREA
	PUSHJ	P,IADRCK##	; ..
	  JRST	ADRERR##	;NO GOOD
	MOVSI	P1,440700	;SEVEN BIT BYTES, RELOCATED.
	HRRI	P1,-21(T1)	;IN USER AREA
	MOVEI	P2,<21*5>-1	;NUMBER OF BYTES ALLOWED
	PUSHJ	P,TWAITC	;GET AT LEAST ONE CHARACTER
DDTINL:	SKIPG	LDBTIC(U)	;ANY MORE TO COME?
	JRST	DDTINX		;NO.
	PUSHJ	P,TYICC		;YES. GO GET ONE
	  JRST	DDTINX		;WASNT ANY. I'M CONFUSED.
	TRNE	T3,177		;NULL?
	EXCTUU	<IDPB T3,P1>	;NO. STORE IN USER AREA
	SOJG	P2,DDTINL	;IF MORE SPACE, GET ANOTHER CHARACTER
DDTINX:	MOVEI	T3,0		;FLAG END OF STRING
	EXCTUU	<IDPB T3,P1>	; IN USER AREA
	PJRST	NOCTRO		;AND RETURN TO USER, CLEARING ↑O FLAG

;DDTOUT - CALL AC,[SIXBIT /DDTOUT/], AC/ ADDR, ADDR/ ASCIZ /XXX/

DDTOUT::HRR	M,T1		;USER ADR. OF TEXT TO M
	PUSHJ	P,TTYFNU	;GET USER'S CONSOLE
	PUSHJ	P,CKATOU	;MAKE SURE AT USER LEVEL AND ATTACHED
	JRST	OUTSTR		;SAME AS THE CORRESPONDING TTCALL
	SUBTTL	TTCALL AND TRMOP. -- TTCALL DISPATCH ;⊗ TTYUUO TTUUA TTUUB TTUUC TTUUD TTUUE

;TTCALL AC,E - VALUE OF AC DETERMINES ACTION OF UUO (051)

TTYUUO::PUSHJ	P,SAVE2##	;SAVE P1,P2
	PUSHJ	P,TTYFNU	;FIND CURRENT USER'S TTY
	MOVE	P2,TTUUOT(P1)	;GET PRE-CHECK BITS
	TLNE	P2,TC.ATW	;ATTACH OR WAIT?
	PUSHJ	P,CKATTO	;YES.  WAIT TILL ATTACHED
TTUUA:	TLNN	P2,TC.ATR	;ATTACH OR RETURN?
	JRST	TTUUB		;NO
	TRNN	U,-1		;YES.  LINE NON-ZERO?
	POPJ	P,0		;NO.  RETURN, NO TERMINAL

TTUUB:	JUMPE	U,TTUUD		;ONE UUO-GETLCH-CAN BE HERE DETACHED
	HLL	U,LDBDCH(U)	;GET LINE DESCRIPTION
	TLNN	P2,TC.USR	;USER OR RETURN?
	JRST	TTUUC		;NO
	TLNE	U,LDLCOM	;YES.  USER LEVEL?
	POPJ	P,0		;NO.  RETURN.

TTUUC:	TLNE	P2,TC.USW	;USER OR WAIT?
	TLNN	U,LDLCOM	;YES.  AT USER LEVEL
	JRST	TTUUD		;USER LEVEL, OR NOT NEEDED
	PUSHJ	P,CKATOU	;TOP LEVEL.WAIT FOR USER.
	JRST	TTYUUO		;RESTART UUO IN CASE OF
				;ATTACH.
TTUUD:	TLNN	P2,TC.ADC	;ADDRESS CHECK NEEDED?
	JRST	TTUUE		;NO.  GO DISPATCH.
	HRRZ	T1,M		;ADDRESS TO P1, WHICH IS P1
	PUSHJ	P,UADCK1##	;CHECK THE ADDRESS
TTUUE:	TLNE	P2,TC.ECS	;INPUT OPERATION?
	PUSHJ	P,TYIEAT	;YES, EAT COMMAND IF LEFT OVER
	JRST	@TTUUOT(P1)	;DISPATCH TO ROUTINE
;THE FOLLOWING TABLE IS USED TO PRE-CHECK AND DISPATCH THE TTCALL'S. ;⊗ TC.ADC TC.USR TC.USW TC.ATW TC.ATR TC.ECS TTUUOT
;BITS IN THE LEFT ARE CHECKED BEFORE DISPATCHING.
;INDIRECT AND INDEX MUST BE ZERO, FOR JRST INDIRECT, BUT THIS COULD
;EASILY BE CHANGED IF THE BITS RUN OUT.


TC.ADC==400000		;THIS FUNCTION MUST BE ADDRESS CHECKED
TC.USR==200000		;THIS FUNCTION MUST BE AT USER LEVEL, ELSE POPJ
TC.USW==100000		;THIS FUNCTION MUST BE AT USER LEVEL, ELSE WAIT
TC.ATW==040000		;THIS FUNCTION MUST BE ATTACHED, ELSE WAIT
TC.ATR==020000		;THIS FUNCTION MUST BE ATTACHED, ELSE POPJ
TC.ECS==010000		;EAT COMMAND SYNC (CALL TYIEAT)
;DON'T ASSIGN BITS 13-17 WITHOUT CHANGING DISPATCH CODE

TTUUOT:	XWD	TC.ATW+TC.USW+TC.ADC+TC.ECS,INCHRW	;(00) INPUT CHARACTER, WAIT
	XWD	TC.ATW+TC.USW,ONEOUT		;(01) OUTPUT CHARACTER
	XWD	TC.ATR+TC.USR+TC.ADC+TC.ECS,INCHRS	;(02) INPUT CHARACTER, SKIP
	XWD	TC.ATW+TC.USW,OUTSTR		;(03) OUTPUT AN ASCIZ STRING
	XWD	TC.ATW+TC.USW+TC.ADC+TC.ECS,INCHWL	;(04) INPUT CHARACTER, WAIT LINE MODE
	XWD	TC.ATR+TC.USR+TC.ADC+TC.ECS,INCHSL	;(05) INPUT CHARACTER, SKIP LINE MODE
	XWD	TC.ADC,GETLIN			;(06) GET LINE CHARACTERISTICS
	XWD	TC.ATW+TC.ADC,SETLIN		;(07) SET LINE CHARACTERISTICS
	XWD	TC.ATR,TRESCU			;(10) RESCAN COMMAND LINE
	XWD	TC.ATR,TSETBI			;(11) CLEAR INPUT BUFFER
	XWD	TC.ATR,TSETBO			;(12) CLEAR OUTPUT BUFFER
	XWD	TC.ATR+TC.USR+TC.ECS,SKPINC	;(13) SKIP IF A CHAR TO BE INPUT
	XWD	TC.ATR+TC.USR+TC.ECS,SKPINL	;(14) SKIP IF A LINE TO BE INPUT
	XWD	TC.ATW+TC.USW,IONEOU		;(15) IMAGE ONE-CHARACTER OUTPUT
	XWD	0,CPOPJ##			;(16) NOT IMPLEMENTED
	XWD	0,CPOPJ##			;(17) NOT IMPLEMENTED
	SUBTTL	TTCALL AND TRMOP. -- OUTCHR AND IMAGE OUTCHR ;⊗ ONEOUT ONEOU1 IONEOU

;ONEOUT OUTPUTS ONE CHARACTER FROM C(E)

ONEOUT:	PUSHJ	P,SAVE2##	;SAVE P2
	SKIPN	F		;ANY DDB?
	SKIPA	P2,[CCTYO]	;NO--MUST BE SLOPPY
	MOVEI	P2,TYO7W	;YES--BE NEAT
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
ONEOU1:	PUSHJ	P,GETWDU##	;PICK UP USER'S WORD
	MOVE	T3,T1		;PUT IN RIGHT AC
	ANDI	T3,177		;MASK OUT ANY JUNK
	JUMPE	T3,CPOPJ##	;IF NOT NULL,
	PJRST	(P2)		;TYPE OUT, WITH PARITY, WAIT IF NEEDED

;IONEOU OUTPUTS ONE CHARACTER FROM LOW 8 BITS OF C(E)
IONEOU:
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
	PUSHJ	P,CLRIIQ	;NOT IN INPUT WAIT ANY MORE
	JUMPE	F,ONEOU1	;IF NO DDB, SEND 7 BITS
	PUSHJ	P,GETWDU##	;GET USER'S DATUM
	HRRZ	T3,T1		;INTO RIGHT AC
	TRO	T3,400		;FLAG AS IMAGE CHARACTER (NO FILLER)
	PJRST	TYO9W		;SEND IMAGE CHARACTER (WAIT IF NEEDED)
	SUBTTL	TTCALL AND TRMOP. -- OUTSTR AND RESCAN ;⊗ OUTSTR OUTST3 OUTST6 OUTST5 OUTST2 OUTST1 OUTST4 TRESCU

;OUTSTR OUTPUTS A STRING OF ASCIZ CHARACTERS

OUTSTR:
IFN FTRSP,<PUSHJ P,RSPTOR##>	;RECORD RESPONSE SATISFIED BY TERMINAL OUTPUT
	PUSHJ	P,SAVE4##	;SAVE P1-P4
	MOVEI	P3,TYO7W
OUTST3:	LDB	T1,[POINT 9,M,26] ;PAGE #
	PUSHJ	P,TPSHS##	;IS PAGE SHARED?
	  JRST	OUTST6		;YES -- JUST USE
	HRROI	T1,(M)		;LEFT JUSTIFIED ASCIZ STRING
	PUSHJ	P,CKSTR##	;MAKE SURE ITS IN CORE AND LEGAL
	  JRST	UADERR##	;ADDRESS CHECK
OUTST6:	HRRI	M,-1(M)		;COMPENSATE FOR GETWD1
OUTST5:	MOVEI	P4,200		;MAXIMUM # OF WORDS IN ONE SHOT
OUTST2:	MOVE	P1,[POINT 7,P2]	;PREPARE TO READ BYTES
	PUSHJ	P,GETWD1##	;GET A USER'S WORD
	MOVE	P2,T1		;PUT WORD IN A SAFE AC
OUTST1:	TLNN	P1,760000	;ANY BYTES LEFT?
	JRST	OUTST4		;NO. GET ANOTHER WORD
	ILDB	T3,P1		;YES. GET ONE
	JUMPE	T3,CPOPJ##	;NULL MARKS END OF STRING
	PUSHJ	P,(P3)		;TYPE OUT CHARACTER WITH PARITY
	JRST	OUTST1		;AND GO BACK FOR MORE.

OUTST4:	SOJG	P4,OUTST2	;GO BACK FOR MORE. IS MESSAGE LONG?
	PUSHJ	P,SCDCHK##	;GIVE THE REST OF THE WORLD A CHANCE
	JRST	OUTST5

;TRESCU IS RESCAN FUNCTION FOR PROGRAM TO READ COMMAND THAT STARTED IT

TRESCU:	MOVE	T2,LDBBY2(U)	;SAVE OLD BIT FOR TEST
	MOVEI	T1,L2RECS	;CLEAR BIT IN LINE DATA BLOCK WHICH
	ANDCAM	T1,LDBBY2(U)	; WOULD CAUSE COMMAND TO BE SKIPPED
	TDNN	T2,T1		;SEE IF ANYTHING THERE
	TRNN	M,1		;NO--SEE IF USER WANTS TO KNOW
	POPJ	P,0		;NO--JUST RETURN
	JRST	CPOPJ1##	;YES--GIVE SKIP RETURN
	SUBTTL	TTCALL AND TRMOP. -- SKPINL AND SKPINC ;⊗ SKPINL SKPINC NOCTRO STCTRO

;SKIP IF A LINE MAY BE INPUT

SKPINL:	PUSHJ	P,TYIEAT	;MAKE SURE NOT FAKED BY COMMAND
	PUSHJ	P,NOCTRO	;CLEAR THE ↑O BIT
	PJRST	TTLCHK		;CHECK FOR LINE READY
				; AND RETURN SKIP/NON-SKIP

;SKIP IF A CHARACTER MAY BE INPUT

SKPINC:	PUSHJ	P,TYIEAT	;MAKE SURE NOT FAKED BY COMMAND
	SKIPG	LDBTIC(U)	;ANY WAITING TO INPUT
	SKIPLE	LDBECC(U)	; OR WAITING FOR ECHO?
	AOS	(P)		;SAY SOMETHING'S THERE
	PJRST	NOCTRO		;AND CLEAR CTRL/O



NOCTRO:	MOVEI	T1,LDROSU	;CLEAR OUTPUT SUPPRESS BIT
	ANDCAM	T1,LDBDCH(U)	; IN LINE DATA BLOCK
	POPJ	P,0		;AND RETURN

STCTRO:	MOVEI	T1,LDROSU	;THE OUTPUT SUPPRESS BIT
	IORM	T1,LDBDCH(U)	;SET OUTPUT SUPPRESSION
	DPB	T1,LDPSVC	;CLEAR OUT ANY SAVED CHARACTER
	PJRST	TSETBO		;CLEAR OUTPUT BUFFER
	SUBTTL	TTCALL AND TRMOP. -- GETLIN ;⊗ GL.ITY GL.CTY GL.DSP GL.DSL GL.HDP GL.REM GL.RBS GL.LIN GL.SLV GL.LCM GL.TAB GL.LCP GL.PTM GETLIN GETLN1 GETLNZ


;DEFINE THE BITS FOR THE USER ARGUMENT TO GETLIN AND SETLIN

	GL.ITY==400000		;
	GL.CTY==200000		;CTY
	GL.DSP==100000		;TTY DISPLAY
	GL.DSL==040000		;DATA SET LINE
	GL.HDP==010000		;HALF DUPLEX
	GL.REM==004000		;REMOTE TTY, NO [1,2] LOGIN
	GL.RBS==002000		;NETWORK LINE
	GL.LIN==000100		;LINE OF INPUT READY
	GL.SLV==000040		;TTY SLAVE
	GL.LCM==000020		;TTY LOWER CASE
	GL.TAB==000010		;TTY TAB
	GL.LCP==000004		;TTY NO ECHO
	GL.PTM==000002		;TTY PAPER TAPE

;GETLIN RETURNS A WORD OF INFORMATION ABOUT A LINE

GETLIN:	PUSHJ	P,GETWDU##	;GET "ADDR"
	JUMPL	T1,GETLN1	;DOES HE WANT HIS OWN LINE
	TRZ	T1,.UXTRM	;CLEAR THE TTY IO INDEX BIT
	CAIL	T1,TTPLEN##	;LEGAL TTY?
	  JRST	GETLNZ		;NO, RETURN A ZERO
	MOVE	U,LINTAB##(T1)	;GET THE LDB ADDRESS

GETLN1:	JUMPE	U,GETLNZ	;NO LDB, NO BITS!
	LDB	T1,LDPLNO	;COPY THE LINE # FROM THE LDB
	TRO	T1,.UXTRM	;SET THE TERMINAL INDEX BIT

;SET BITS FROM THE (RH) OF LDBDCH(U)

	MOVE	T2,LDBDCH(U)	;GET THE CHARACTERISTICS WORD
	TRNE	T2,LDRPTY	;PTY LINE?
	  TLO	T1,GL.ITY	;YES
	TRNE	T2,LDRCTY	;CTY LINE?
	  TLO	T1,GL.CTY	;YES
	TRNE	T2,LDRDSD	;DATA SET LINE?
	  TLO	T1,GL.DSL	;YES
	TRNE	T2,LDRHLF	;HALF DUPLEX?
	  TLO	T1,GL.HDP	;YES
	TRNE	T2,LDRRMT	;NETWORK LINE?
	  TLO	T1,GL.REM	;YES
	TRNE	T2,LDRREM	;REMOTE STATION LINE?
	  TLO	T1,GL.RBS	;YES

;SET BITS FROM THE (LH) OF LDBCH(U)

	TLNE	T2,LDLSLV	;SLAVE?
	  TLO	T1,GL.SLV	;YES
	TLNN	T2,LDLLCT	;LOWER CASE TRANSLATION?
	  TLO	T1,GL.LCM	;YES
	TLNE	T2,LDLTAB	;TTY TAB?
	  TLO	T1,GL.TAB	;YES
	TLNE	T2,LDLLCP	;LOCAL COPY?
	  TLO	T1,GL.LCP	;YES

;SET BITS FROM THE (LH) OF LDBPAG(U)

	MOVE	T2,LDBPAG(U)	;GET THE PAGE MODE WORD
	TLNE	T2,LPLDIS	;DISPLAY MODE?
	  TLO	T1,GL.DSP	;YES

;SET BITS FROM THE (RH) OF LDBBY2

	MOVE	T2,LDBBY2(U)	;GET THE SECOND BYTE WORD
	TRNE	T2,L2RXON	;PAPTER TAPE MODE?
	  TLO	T1,GL.PTM	;YES

;FIND OUT IF WE HAVE A LINE OF INPUT READY

	MOVE	T3,T1		;CLOBBERS T1
	PUSHJ	P,TTLCK2	;CHECK FOR A READY LINE
	  TDZA	T1,T1		;NO LINE READY YET
	MOVSI	T1,GL.LIN	;READY BIT
	IOR	T1,T3		;A LINE IS READY
	PJRST	PUTWDU##	;GIVE RESULT TO THE USER

;HERE WHEN WE HAVE FOUND AN ERROR TO RETURN ZERO

GETLNZ:	MOVEI	T1,0		;GET A ZERO AND
	PJRST	PUTWDU		;RETURN IT TO INDICATE AN ERROR
	SUBTTL	TTCALL AND TRMOP. -- SETLIN, INCHSL, INCHWL, INCHRS & INCHRW ;⊗ SETLIN L2PXON SETLP1 INCHRS ICS3 INCHSL INCHWL ICW1 INCHRW

;ROUTINE TO SET LINE CHARACTERISTICS FOR THE CURRENT LINE (U)

SETLIN:	PUSHJ	P,GETWDU##	;GET THE BITS
	HLRZS	T1		;GET THEM IN THE RH
	SETZ	T2,		;CLEAR T2
	TRNE	T1,GL.PTM	;SET PAPER TAPE MODE?
	  MOVEI	T2,1		;YES
	DPB	T2,L2PXON	;SET THE BIT
	SETZ	T2,		;CLEAR T2
	TRNE	T1,GL.DSP	;DISPLAY MODE?
	  MOVEI	T2,1		;YES
	DPB	T2,LDPDIS	;SET THE BIT
	TRC	T1,GTLT37	;STORED AS COMPLEMENT
	ROT	T1,-2		;BIT DEPENDENT FOR DPB BELOW
	DPB	T1,SETLP1	;THESE THREE BITS CAN BE SET
	PJRST	SETCHP		;LET THE NETWORK KNOW IF WE
				;CHANGE ANYTHING

;BYTE POINTERS NEEDED BY SETLCH

L2PXON:	POINT	1,LDBBY2(U),18	;PAPER TAPE BIT

SETLP1:	POINT	3,LDBDCH(U),15	;PART OF LEGAL BITS

INCHRS:	PUSHJ	P,SKPINC	;CAN I GET A CHARACTER (CLEAR ↑O)
	  POPJ	P,0		;NO. GIVE NON-SKIP RETURN
	PUSHJ	P,TWAITC	;WAIT IN CASE NOT ECHOED YET
ICS3:	PUSHJ	P,TYIS		;GET A CHARACTER
	  JRST	NOCTRO		;NONE THERE.
	AOS	0(P)		;GIVE SKIP RETURN
	JRST	ICW1		;AND RETURN THE CHARACTER

INCHSL:	PUSHJ	P,SKPINL	;IS THERE A LINE AVAILABLE?
	  POPJ P,0		;NO. NON-SKIP RETURN TO USER
	PUSHJ	P,TWAITL
	JRST	ICS3		;YES. GO GET A CHARACTER FOR HIM

INCHWL:	PUSHJ	P,TWAITL	;WAIT FOR A LINE TO APPEAR
	PUSHJ	P,TYI		;GO GET A CHARACTER
	  MOVEI	T3,0		;IMPOSSIBLE. NO CHARACTERS. USER SET IODERR?
ICW1:	ANDI	T3,177		;MASK TO SEVEN BITS
	MOVE	T1,T3
	PUSHJ	P,PUTWDU##	;GIVE HIM THE CHARACTER
	JRST	NOCTRO		;AND NON-SKIP RETURN

INCHRW:	PUSHJ	P,TWAITC	;WAIT FOR A CHARACTER TO APPEAR
	PUSHJ	P,TYI		;GO GET THE CHARACTER
	  MOVEI	T3,0		;IMPOSSIBLE. NONE THERE. USER SET IODERR?
	JRST	ICW1		;GIVE HIM T3 AND RETURN
	SUBTTL	TTCALL AND TRMOP. -- TRMNO. UUO ;⊗ TRMNO

;TRMNO.	CALLI, TO GET TERMINAL NUMBER
;FOR SPECIFIED JOB NUMBER.
;	MOVE	AC,JOBNUMBER
;CALL	CALLI	AC,115
;	.ERROR RETURN
;	NORMAL RETURN		;AC HAS .UXTRM+LINE#

TRMNO::	CAMN	T1,[-1]		;IS ARG -1?
	MOVEI	T1,(J)		;YES, USE THIS JOB
	JUMPLE	T1,RTZER##	;ERROR IF JOB # 0 OR LESS THAN -1
	CAMLE	T1,HIGHJB##	; OR TOO BIG
	JRST	RTZER##		;..
	HRRZ	T1,TTYTAB##(T1)	;GET DDB ADDRESS
	JUMPE	T1,RTZER##	;ERROR IF NONE
	HRRZ	U,DDBLDB(T1)	;GET LDB ADDRESS
	JUMPE	U,RTZER##	;ERROR IF DETACHED
	LDB	T1,LDPLNO	;GET LINE NUMBER
	ADDI	T1,.UXTRM	;CONVERT TO UNIVERSAL
	JRST	STOTC1##	;SKIP RETURN INDEX TO USER
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. DISPATCH ;⊗ TRMOP TRMNRM

;TRMOP. UUO, OR CALLI 116.
;UUO TO PERFORM MISCELLANEOUS FUNCTIONS FOR
;A SPECIFIED TERMINAL.
;
;CALL:	MOVE	AC,[XWD N,ADR]
;	CALLI	AC,116
;	  ERROR	RETURN
;	NORMAL	RETURN
;

TRMOP::	PUSHJ	P,SAVE4##	;SAVE THE PRESERVED AC'S
	MOVE	P4,T1		;USER'S ARGUMENT TO P4
	HRRM	T1,M		;ADDRESS OF ARGUMENT LIST
	HLRZ	T2,T1		;CHECK FOR LENGTH AT LEAST 2
	CAIL	T2,2
	PUSHJ	P,GETWRD##	;GET USER'S ARG AT M
	  JRST	TOPX3		;ERROR CODE 3, ILLEGAL ADDRESS
	TLNE	T1,-1		;IF BITS IN L.H.
	JRST	RTZER##		; THEN BAD FUNCTION
	HRRZ	P1,T1		;COPY USER ARGUMENT
	JUMPLE	P1,RTZER##	;ZERO ERROR IF BAD ARGUMENT CODE
	PUSHJ	P,GETWR1##	;GET IT, IF POSSIBLE
	  JRST	TOPX3		;NOT A LEGAL ADDRESS
	SUBI	T1,.UXTRM	;REMOVE TERMINAL OFFSET
	CAME	T1,[-1-.UXTRM]	;WANTS CONTROLLING TTY?
	JRST	TRMNRM		;NO
	HRRZ	T1,TTYTAB##(J)	;YES, GET DDB ADDRESS
	JUMPE	T1,RTZER##	;ERROR IF NONE
	HRRZ	U,DDBLDB(T1)	;GET LDB ADDRESS
	JUMPE	U,RTZER##	;DETACHED
	LDB	T1,LDPLNO	;GET LINE NUMBER
TRMNRM:	JUMPL	T1,RTZER##	;RANGE CHECK THE TERMINAL #
	CAIL	T1,TTPLEN##	;..
	  JRST	RTZER##		;BAD LINE NUMBER
	HRRZ	U,LINTAB##(T1)	;OK. GET THE LDB ADDRESS
	HRRZ	F,LDBDDB(U)	;AND DDB, IF ANY.
	JUMPN	F,TRMO1		;DID WE FIND M DDB?
	HRLZ	T2,LDBDCH(U)	;NO, GET LINE STATUS
	JUMPGE	T2,TRMO1	;PTY?
	SUBI	T1,TCONLN##+1	;YES, GET NUMBER
	HRRZ	F,PTYTAB(T1)	;GET DDB ADDR


;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ TRMO1 CHKRED CHKWRT CHKDDB

TRMO1:	MOVE	T1,P1		;GET USER'S FUNCTION CODE
	TRNE	T1,3000		;READ/SET CODE?
	JRST	TOPRSQ		;PROBABLY. GO SEE.
	CAILE	T1,TOPLN0	;IS IT AN ACTION CODE?
	JRST	RTZER##		;NO. NO SUCH CODE
	HRRI	M,1(M)		;ADVANCE M
	MOVE	P3,TOPTB0-1(T1)	;PICK UP DISPATCH WORD
IFN FTMIC,<
	MOVSI	P2,(JB.LSY)	;PROGRAM FROM SYS BIT
	TLNE	P3,(TOP.MC)	;MIC TRMOP?
	TDNN	P2,JBTLIM##(J)	;AND DID THIS PROGRAM COME FROM SYS?
	JRST	CHKRED		;NO TO EITHER
	MOVSI	P2,'MIC'	;RUNNING MIC?
	CAMN	P2,JBTNAM##(J)	;SKIP IF NO
	JRST	CHKDDB		;RUNNING MIC, NO FUTHER CHECKING REQUIRED
CHKRED:	MOVSI	T1,JP.POK
	TLNE	P3,(TOP.MR)
	PUSHJ	P,PRVBIT
	  SKIPA
	JRST	TOPX1
>
	TLNN	P3,(TOP.RP)	;DO WE NEED READ PRIVS?
	JRST	CHKWRT		;NO--SEE IF WE NEED WRITE PRIVS
	PUSHJ	P,TREDOK	;YES--DO WE HAVE READ PRIVS?
	  JRST	TOPX1		;NO--GIVE ERROR RETURN
CHKWRT:	TLNN	P3,(TOP.WP)	;DO WE NEED WRITE PRIVS?
	JRST	CHKDDB		;NO--DISPATCH
	PUSHJ	P,TWRTOK	;YES--DO WE HAVE READ PRIVS?
	  JRST	TOPX1		;NO--GIVE ERROR RETURN
CHKDDB:	TLNN	P3,(TOP.NF)	;NEED F?
	JRST	(P3)		;NO--ALLSET
	PUSHJ	P,TOPDDB	;YES--GET DDB
	  JRST	TOPX6		;CAN'T GIVE ERROR
	JRST	(P3)		;YES--DO THE TRMOP.
;HERE IF REQUESTED FUNCTION NOT FROM 1 THRU TOPLN0-1 ;⊗ TOPRSQ TOPSET TOPST1 TOPST2 TOPST3
;F AND U ARE SET UP TO THE DESIRED LINE.

TOPRSQ:	ANDI	P1,777		;JUST THE ITEM NUMBER
	TRZE	T1,1000		;READ CODE?
	JRST	TOPRED		;PROBABLY
	CAIL	T1,2000+TOPLN1	;NO. SET CODE?
	JRST	RTZER##		;NOT A LEGAL CODE
TOPSET:	HLRZ	T2,P4		;IS THERE ANOTHER DATUM?
	CAIGE	T2,3		;..
	JRST	TOPX3		;NO. CAN'T DO THE SET.
	HRRI	M,1(M)		;YES. GO GET IT
	PUSHJ	P,GETWRD##	;..
	  JRST	TOPX3		;NOT A LEGAL ADDRESS
	MOVE	P2,T1		;SAVE ARGUMENT
	PUSHJ	P,TWRTOK	;DOES HE HAVE WRITE PRIVS?
	  JRST	TOPX1		;NO. ERROR CODE 1.
TOPST1:	LDB	T1,TOPSYR	;LEGAL TO TRY SETTING.
	JUMPE	T1,TOPST2	;RANGE CHECK REQUIRED?
	HLRZ	T2,TOPSRT-1(T1)	;YES. GET MINIMUM VALUE
	CAMGE	P2,T2		;SUPPLIED .GE. MINIMUM?
	JRST	TOPX2		;NO. BAD ARG, TOO SMALL
	HRRZ	T2,TOPSRT-1(T1)	;OK. CHECK MAXIMUM
	CAMLE	P2,T2		;..
	JRST	TOPX2		;BAD. ARG TOO BIG.
TOPST2:	SKIPN	T2,TOPTB1(P1)	;SET ALLOWED?
	PJRST	RTZER##		;ILLEGAL/UNKNOWN FUNCTION
TOPST3:	TLNE	T2,(TOP.SA)	;OK TO SET?
	JRST	TOPST4		;YES--DO SO
	TLNN	T2,(TOP.PS)	;NEED PRIVS?
	JRST	TOPX1		;NO--CAN NOT SET
	MOVSI	T1,JP.POK	;POKE BIT
	PUSHJ	P,PRVBIT##	;IS IT SET?
	  JRST	TOPST4		;YES--DO SET
	JRST	TOPX1		;NO. NOT ALLOWED.
TOPST4:	TLNN	T2,(TOP.IF)	;THIS FUNCTION ILLEGAL FOR FRCLIN? ;⊗ TOPST4 TOPST5 TOPTFE
	JRST	TOPST5		;NO, CONTINUE
	LDB	T1,LDPLNO	;GET LINE NUMBER
	CAIN	T1,FRCLIN##	;IS IT FRCLIN?
	JRST	TOPX1		;YES, ILLEGAL
TOPST5:	TLNE	T2,(TOP.RT)	;NEED A ROUTINE TO SET?
	PJRST	1(T2)		;YES, SET ROUTINE IS ADDRESS+1
	LDB	T1,0(T2)	;FETCH WHAT THE STATE IS CURRENTLY
	CAMN	T1,P2		;WILL IT CHANGE?
	JRST	CPOPJ1		;NO, DON'T SEND STATUS CHANGE THEN
	MOVEI	T1,LDRPTY	;THE LINE-IS-A-PTY BIT
	CAIN	P1,4		;SET SLAVE?
	TDNN	T1,LDBDCH(U)	; ON PTY?
	DPB	P2,0(T2)	;OK. CHANGE ITEM.
IFN FTD10H,<
	CAIN	P1,27		;ARE WE SETTING APL?
	DPB	P2,[POINT 1,LDBBCD(U),11] ;YES, SET IT WHERE DLSINT
				; LOOKS FOR IT
>
TOPTFE:	MOVSI	T1,(TOP.PE)	;DO WE NEED TO CHANGE
	TDNN	T1,TOPTB1(P1)	; HARDWARE PARAMS FOR THIS LINE
	JRST	CPOPJ1##	;NO--JUST RETURN
	PUSHJ	P,SETCHP
	JRST	CPOPJ1##	;SKIP RETURN
TOPRED:	CAIL	T1,TOPLN1	;LEGAL ITEM NUMBER? ;⊗ TOPRED TOPRD1 TOPOIP TOPHPS TOPHPR
	JRST	RTZER##		;NO. ERROR RETURN
	PUSHJ	P,TREDOK	;OK TO DO A READ?
	  JRST	TOPX1		;NO. PROTECTION FAILURE.
	SKIPN	T1,TOPTB1(P1)	;OK. GET TABLE ENTRY.
	JRST	RTZER##		;ILLEGAL/UNKNOWN FUNCTION
	TLNE	T1,(TOP.RT)	;NEED A ROUTINE
	JRST	TOPRD1		;YES, GO DISPATCH
	LDB	T1,0(T1)	;GET BYTE POINTED TO
	PJRST	STOTC1##	;AND RETURN IT TO USER

TOPRD1:	PUSHJ	P,0(T1)		;ZERO OFFSET TO READ
	PJRST	STOTC1		;RETURN RESULT TO USER AND SKIP RETURN


;ROUTINE TO HANDLE FUNCTION 1000

TOPOIP:	PUSHJ	P,TOPSOP	;SKIP RETURN IF MORE TO OUTPUT
	TDZA	T1,T1		;CLEAR BUSY FLAG,OUTPUT DONE
	MOVEI	T1,1		;SET BUSY FLAG
	POPJ	P,		;RETURN
;ROUTINE TO FETCH/SET THE VALUE OF HPOS

TOPHPS:	JRST	TOPHPR		;HERE FOR READ
	LDB	T2,LDPWID	;HERE FOR SET.  GET CARRIAGE WIDTH
	MOVNS	T2		;MINUS
	ADD	T2,P2		;PLUS USERS ARGUMENT
	MOVEM	T2,LDBHPS(U)	;SETUP IN LDB
	JRST	CPOPJ1##	;AND SIGNAL GOOD RETURN

TOPHPR:	PUSHJ	P,HPOS		;GET POSITION
	MOVE	T1,T2		;GET INTO CORRECT AC
	POPJ	P,
;ROUTINE TO HANDLE FUNCTION 1041 ;⊗ TOPTTC TOPTT1 TOPSUP TOPSU2 TOPSU5 TOPCCT

TOPTTC:	JRST	TOPTT1		;GET TERMINAL TYPE
	MOVE	T2,P2		;GET USER'S ARGUMENT
	PUSHJ	P,TTUTYP##	;SET TERMINAL CHARACTERISTICS
	  JRST	TOPX2		;UNKNOWN TERMINAL TYPE
	JRST	CPOPJ1##	;GOOD RETURN

TOPTT1:	LDB	T1,LDPTTT	;GET TERMINAL TYPE
	TRZE	T1,100		;CUSTOMER DEFINED TERMINAL TYPE ?
	MOVNS	T1		;YES
	MOVE	T1,TTTWDT##(T1)	;GET TERMINAL NAME
	POPJ	P,		;STORE ANSWER FOR THE USER AND RETURN



;ROUTINE TO HANDLE FUNCTION 1045 (READ/SET ↑O STATE)

TOPSUP:	JRST	TOPSU5		;READ AND RETURN
	TRNE	P2,1		;SET OR CLEAR ↑O?
	JRST	TOPSU2		;SET IT
	PUSHJ	P,NOCTRO	;CLEAR IT
	JRST	CPOPJ1##	;RETURN HAPPILY

TOPSU2:	PUSHJ	P,STCTRO	;SET ↑O STATE
	JRST	CPOPJ1##	;RETURN SUCCESSFULLY

TOPSU5:	LDB	T1,LDPOSU	;GET ↑O BIT
	POPJ	P,		;AND RETURN IT TO USER



;ROUTINE TO RETURN TOTAL INPUT CHARACTER COUNT

TOPCCT:	MOVE	T1,LDBTIC(U)	;INPUT CHARACTER COUNT AVAILABLE TO USER
	ADD	T1,LDBECC(U)	;PLUS THOSE NOT YET ECHOED
	POPJ	P,		;RETURN TOTAL MONITOR CHARACTER COUNT
;SUBROUTINE TO CHECK FOR READ PRIVS ;⊗ TREDOK TWRTOK MYTTY MYTTY2 MYTTY1
;CALL WITH:
;	F = DDB OF TARGET OR 0
;	PUSHJ	P,TREDOK
;	  RETURN HERE IF ERROR
;	RETURN HERE IF OK TO READ

TREDOK:	PUSHJ	P,SAVE3##	;SAVE P1,P2 AND P3
	MOVSI	P1,PVSPYM!PVSPYA;LOAD UP THE SPY BIT
	JRST	MYTTY		;JUMP TO COMMON CODE

;SUBROUTINE TO CHECK FOR WRITE PRIVS
;CALL WITH:
;	F = DDB OF TARGET OR 0
;	PUSHJ	P,TWRTOK
;	  RETURN HERE IF ERROR
;	RETURN HERE IF OK
;PRESERVES ALL AC'S

TWRTOK:	PUSHJ	P,SAVE3##	;SAVE P1,P2 AND P3
	MOVSI	P1,JP.POK	;FALL INTO COMMON CODE
MYTTY:	SKIPE	P2,F		;IS THERE A DDB?
	LDB	P2,PJOBN##	;YES--GET THE OWNERS JOB NUMBER
	CAMN	P2,J		;DO I OWN THIS TERMINAL
	JRST	MYTTY1		;CHECK PRIVS FOR MIC STYLE TRMOP
MYTTY2:	EXCH	P1,T1		;SAVE T1 AND SET UP PRIV BIT
	PUSHJ	P,PRVBIT##	;CHECK THE BIT
	  AOS	(P)		;OK TO READ OR SET
	MOVE	T1,P1		;RESTORE T1
	POPJ	P,0		;RETURN

MYTTY1:	
IFE FTMIC,<JRST CPOPJ1##>	;OK TO DO YOUR THING
IFN FTMIC,<
	TLNN	P3,(TOP.MC)	;MIC TRMOP?
	JRST	CPOPJ1##	;NO--OK TO DO YOUR THING
	MOVE	P2,DEVMOD(F)	;IS THE TARGET TTY...
	TLNE	P2,TTYATC	;CONTROLLING HIS JOB?
	JRST	CPOPJ1##	;YES--OK TO DO MIC TRMOP
	MOVE	P2,LDBDCH(U)	;NO--IS THE TARGET TTY...
	TRNE	P2,LDRCTY	;A CTY?
	JRST	MYTTY2		;YES--CHECK PRIVS
	CAMN	U,OPRLDB##	;IS THIS "OPR"?
	JRST	MYTTY2		;YES--CHECK PRIVS
	HRRZ	P3,TTYTAB##(J)	;GET USER'S TTY DDB ADDRESS
	JUMPE	P3,MYTTY2	;ERROR IF NONE
	HRRZ	P3,DDBLDB(P3)	;USER'S LDB ADDRESS
	JUMPE	P3,MYTTY2	;DETACHED
	MOVE	P3,LDBDCH(P3)	;USER'S TTY CHARACTERISTICS BITS
	TRNN	P3,LDRDSR	;IS HE A LOCAL TTY?
	JRST	CPOPJ1##	;YES--LET HIM DO MIC TRMOP TO EITHER REMOTE OR LOCAL TTY'S
	TRNE	P2,LDRDSR	;NO--TARGET TTY ANOTHER REMOTE TTY?
	JRST	CPOPJ1##	;YES--DO IT
	JRST	MYTTY2		;NO--CHECK PRIVS
>
;ERROR RETURNS ;⊗

ERCODE	TOPX1,TRMNP%		;(1) ERROR CODE FOR PROT CHECK
ERCODE	TOPX2,TRMBR%		;(2) ERROR CODE FOR RANGE BAD
ERCODE	TOPX3,TRMIA%		;(3) ERROR CODE FOR ADDRESS BAD.
ERCODE	TOPX4,TRMCD%		;(4) ERROR CODE FOR NOT POSSIBLE TO DO
ERCODE	TOPX5,TRMDO%		;(5) ERROR IN DIALLER OPERATION
ERCODE	TOPX6,TRMND%		;(6) CAN NOT GET DDB
;TOPTB0 - TRMOP. ACTION FUNCTIONS LESS THAN 1000  ;⊗ TOP.RP TOP.WP TOP.NF TOP.MC TOP.MR TOPTB0 TOPLN0

	TOP.RP==1B1		;NEED READ PRIVS TO DO THIS FUNCTION
	TOP.WP==1B2		;NEED WRITE PRIVS TO DO THIS FUNCTION
	TOP.NF==1B3		;NEED F SETUP TO DO THIS FUNCTION
IFN FTMIC,<
	TOP.MC==1B4		;THIS FUNCTION IS LEGAL IF RUNNING MIC
	TOP.MR==1B5		;FUNCTION REQUIRES MIC
>

IF2,<
IFNDEF	TOPABR,<TOPABR==RTZER##>
IFNDEF	TOPELE,<TOPELE==RTZER##>
> ;END IF2 CONDITIONAL

TOPTB0:	EXP	TOP.RP+TOPSIP			;1 - SKIP IF INPUT PRESENT
	EXP	TOP.RP+TOPSOP			;2 - SKIP IF OUTPUT PRESENT
	EXP	TOP.WP+TOPCIB			;3 - CLEAR INPUT BUFFER
	EXP	TOP.WP+TOPCOB			;4 - CLEAR OUTPUT BUFFER
	EXP	TOP.RP+TOP.WP+TOPOUC		;5 - OUTPUT CHAR
	EXP	TOP.RP+TOP.WP+TOP.NF+TOPOIC	;6 - OUTPUT IMAGE CHAR
	EXP	TOP.RP+TOP.WP+TOPOUS		;7 - OUTPUT STRING
	EXP	TOP.RP+TOP.WP+TOPINC		;10 - INPUT CHAR
	EXP	TOP.RP+TOP.WP+TOPIIC		;11 - INPUT IMAGE CHAR
	EXP	TOP.WP+TOPDSE			;12 - DATASET ENABLE
	EXP	TOP.WP+TOPDSC			;13 - DATASET CALL
	EXP	TOP.WP+TOPDSF			;14 - DATASET OFF
	EXP	TOP.RP+TOP.WP+TOPRES		;15 - RESCAN
	EXP	TOP.WP+TOPELE			;16 - SET TYPE ELEMENT
	EXP	TOP.WP+TOPABR			;17 - ENABLE AUTO BAUD DETECT
	EXP	TOP.RP+TOP.WP+TOPISC		;20 - INPUT CHAR.
	EXP	TOP.RP+TOP.WP+IFN FTMIC,<TOP.MC>+TOPMTY	;21 - MICTYP
IFN FTMIC,<
	EXP	TOP.RP+TOP.WP+TOP.MC+TOPMGT	;22 - MICGET
	EXP	TOP.RP+TOP.WP+TOP.MC+TOP.MR+TOPMST;23 - MICSET
	EXP	TOP.RP+TOP.WP+TOP.MC+TOPMCL	;24 - MICCLR
>
IFE FTMIC,<
	EXP	RTZER##				;22 - NOT IMPLEMENTED
	EXP	RTZER##				;23 - NOT IMPLEMENTED
	EXP	RTZER##				;24 - NOT IMPLEMENTED
>
	EXP	TOP.RP+TOP.WP+IFN FTMIC,<TOP.MC>+TOPMDP	;25 - MICDPY
IFN FTMIC,<
	EXP	TOP.RP+TOP.WP+TOP.MC+TOPMRS	;26 - MICDSP
IFN FTMLOG,<
	EXP	TOP.MC+TOP.RP+TOP.WP+TOPMLG	;27 - MICLOG
>
IFE FTMLOG,<
	EXP	RTZER##				;27 - NOT IMPLEMENTED
>
>
IFE FTMIC,<
	EXP	RTZER##				;26 - NOT IMPLEMEMTED
	EXP	RTZER##				;27 - NOT IMPLEMENTED
>
	EXP	TOPDSS				;30 - RETURN DATA SET STATUS
TOPLN0==.-TOPTB0
IFN FTPATT,<BLOCK 1>				;   - FOR PATCHING
;TOPTB1 - TRMOP. READ/SET FUNCTIONS GREATER THAN 1000 ;⊗ TOP.SA TOP.PS TOP.PE TOP.RT TOP.IF TOPTB1 TOPLN1
;CONTENTS OF TOPTB1 ARE AS FOLLOWS
;BITS 0-5 ARE RANGE TABLE INDEX FOR RANGE CHECK ON SET.
;BITS 6-12 ARE FLAGS FOR DETERMINING LEGALITY OF TRMOP UUO
;RH IS ADDRESS OF BYTE POINTER.

TOP.SA==1B6	;SET ALLOWED
TOP.PS==1B7	;SET ALLOWED FOR PRIVILEGED JOB ONLY
TOP.PE==1B8	;POKE THE FRONT END IF SET
TOP.RT==1B9	;FETCH/SET REQUIRES A ROUTINE.  ENTERED AT ADDRESS+0
		;FOR FETCH, ADDRESS+1 FOR SET.  FETCH ROUTINE MUST
		;RETURN VALUE IN T1.  SET ROUTINE'S RETURN IS PROPAGATED
		;BACK TO USER.
TOP.IF==1B10	;THIS FUNCTION IS ILLEGAL FOR FRCLIN NO MATTER IF
		;THE JOB IS PRIVILEGED OR NOT

;NOTE: THESE DEFINITIONS MUST AGREE WITH LDB DEFINITIONS
TOPTB1:	EXP	<0>B5+<TOP.RT>+<TOPOIP>					;1000
	EXP	<0>B5+<0>+<[POINT 1,LDBDCH(U),↑L<(LDLCOM)>]>		;1001
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBBY2(U),↑L<L2RXON>]>;1002
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPLCT>			;1003
	EXP	<0>B5+<TOP.SA+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<(LDLSLV)>]> ;1004
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPTAB>				;1005
	EXP	<0>B5+<TOP.SA>+<LDPFRM>					;1006
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBDCH(U),↑L<(LDLLCP)>]>;1007
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBDCH(U),↑L<(LDLNFC)>]>;1010
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.RT>+<TOPHPS>			;1011
	EXP	<1>B5+<TOP.SA+TOP.PE>+<LDPWID>				;1012
	EXP	<0>B5+<TOP.SA>+<[POINT 1,LDBBY2(U),↑L<(L2LSND)>]>	;1013
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<LDRHLF>]>	;1014
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<LDRRMT>]>	;1015
	EXP	<0>B5+<TOP.SA>+<[POINT 1,LDBPAG(U),↑L<(LPLDIS)>]>	;1016
	EXP	<2>B5+<TOP.SA+TOP.PE>+<LDPFLC>				;1017
	EXP	<0>B5+<TOP.SA+TOP.PE>+<[POINT 1,LDBBY2(U),↑L<(L2LTAP)>]>;1020
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<[POINT 1,LDBPAG(U),↑L<(LPLPAG)>]>;1021
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<[POINT 1,LDBDCH(U),↑L<(LDLSTP)>]>;1022
	EXP	<3>B5+<TOP.SA+TOP.IF>+<LDPPSZ>				;1023
	EXP	<3>B5+<LDPPCT>						;1024
	EXP	<0>B5+<TOP.SA>+<[POINT 1,LDBPAG(U),↑L<(LPLBLK)>]>	;1025
	EXP	<0>B5+<TOP.SA>+<LDPALT>					;1026
	EXP	<0>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPAPL>			;1027
	EXP	<4>B5+<TOP.SA+TOP.PE>+<LDPRSP>				;1030
	EXP	<4>B5+<TOP.SA+TOP.PE>+<LDPTSP>				;1031
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPDBK>				;1032
	EXP	<0>B5+<TOP.PS+TOP.PE+TOP.IF>+<LDP274>			;1033
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPTDY>				;1034
	EXP	<5>B5+<TOP.SA+TOP.PE+TOP.IF>+<LDPACR>			;1035
	EXP	TOP.SA+LDPRTC						;1036
	EXP	<0>B5+<TOP.SA>+<[POINT 36,LDBPBK(U),35]>		;1037
	EXP	<0>B5+<TOP.SA+TOP.PE>+<LDPDEM>				;1040
	EXP	<0>B5+<TOP.SA+TOP.RT+TOP.IF>+<TOPTTC>			;1041
IFN FTRSP!FTACCT,<
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 36,LDBBCT(U),35]>		;1042
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 36,LDBICT(U),35]>		;1043
	EXP	<0>B5+<TOP.PS+TOP.IF>+<[POINT 36,LDBOCT(U),35]>		;1044
> ;END IFN FTRSP!FTACCT
IFE FTRSP!FTACCT,<EXP 0,0,0>
	EXP	<0>B5+<TOP.SA+TOP.RT>+<TOPSUP>				;1045
	EXP	<0>B5+LDPFCS						;1046
	EXP	<0>B5+LDPBKA						;1047
	EXP	0							;1050
	EXP	0							;1051
	<0>B5+<[POINT 36,LDBTIC(U),35]>					;1052
	EXP	0							;1053
	<0>B5+<[POINT 36,LDBBKC(U),35]>					;1054
	<0>B5+<[POINT 36,LDBECC(U),35]>					;1055
	<0>B5+<TOP.RT>+<TOPCCT>						;1056
	<0>B5+<[POINT 36,LDBTOC(U),35]>					;1057
IFN FTPATT,<
	EXP	0		;FOR PATCHING
	EXP	0		;FOR PATCHING
>
TOPLN1==.-TOPTB1
TOPSYR:	POINT	6,TOPTB1(P1),5	;POINTER TO RANGE TABLE INDEX ;⊗ TOPSYR TOPSRT

;THIS IS THE RANGE TABLE
TOPSRT:	XWD	↑D16,↑D255	;(1)MIN AND MAX WIDTHS
	XWD	0,3		;(2)MIN AND MAX FILLER CLASSES
	XWD	0,↑D63		;(3)MIN AND MAX PAGE LENGTH
	XWD	0,17		;(4)MIN AND MAX SPEED
	XWD	0,↑D200		;(5)AUTO C.R. TABLE
IFN FTPATT,<BLOCK 1>	;FOR PATCHING
	SUBTTL	TTCALL AND TRMOP. -- SKIPS AND CLEARS ;⊗ TOPSIP TOPSOP TOPCIB TOPCOB TOPIIC TOPDSE TOPDSF TOPDSC TOPDSS

TOPSIP==SKPINC

TOPSOP::MOVSI	T2,LPLPOK	;THE TTY QUEUED-BY-TOPOKE BIT
	TDNN	T2,LDBPAG(U)	;IS THE TERMINAL QUEUED FOR SERVICE?
	SKIPL	T2,LDBDCH(U)	;NO, IS SERVICE CURRENTLY ACTIVE?
		.CREF LDLIDL	; (CREF REFERENCE TO SYMBOLIC NAME)
	JRST	CPOPJ1##	;OUTPUT ACTIVE OR TEMINAL QUEUED
	SKIPLE	LDBTOC(U)	;MORE CHARACTERS TO OUTPUT
	JRST	CPOPJ1##	;YES, SKIP RETURN
	MOVE	T2,LDBBYT(U)	;GET DEFER BITS
	TRNE	T2,L1RDEM	;IF DEFERRED ECHO,
	TRNE	T2,L1RDEC!L1RDEL ;  ONLY IF WANTS INPUT
	SKIPN	LDBECC(U)	;ANYTHING TO ECHO
	SKIPE	LDBFLP(U)	;OR OUTPUT FROM FILLERS
	AOS	0(P)		;YES. SKIP RETURN
	POPJ	P,0		;RETURN
TOPCIB:	AOS	0(P)		;SUCCESS RETURN
	PJRST	TSETBI		;CLEAR INPUT BUFFER
TOPCOB:	AOS	0(P)		;SUCCESS RETURN
	PJRST	TSETBO		;CLEAR OUTPUT BUFFER

;FOLLOWING NOT DONE YET
	TOPIIC==RTZER##

IFE FTMODM,<
	TOPDSE==CPOPJ##
	TOPDSF==CPOPJ##
	TOPDSC==CPOPJ##
	TOPDSS==CPOPJ##
>
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O ;⊗ TOPOUC TOPMDP TOPOUS TOPOU1 TOPOIC

;OUTPUT 1 CHAR

TOPOUC:	AOS	(P)
	PUSHJ	P,TOPDDB	;GET A DDB
	  SETZM	F		;NO--DON'T NEED IT BADLY
	JRST	ONEOUT		;TYPE

;OUTPUT A STRING

TOPMDP:	MOVEI	T1,LDROSU	;CLEAR CONTROL O BIT
	ANDCAM	T1,LDBDCH(U)	;SO DATA WILL BE SEEN
	TDZA	F,F		;SO CCTYO WILL BE USED (AVOID TIOW)
TOPOUS:	SETOM	F		;SEARCH FOR A DDB
	AOS	(P)
	PUSHJ	P,GETWDU##	;GET POINTER
	HRRZ	M,T1		;PUT IN RIGHT AC
	JUMPE	F,TOPOU1	;USE CCTYO FOR MIC TYPEOUT
	PUSHJ	P,TOPDDB	;GET DDB
	  JRST	TOPOU1		;IF NO DDB
	HRRZ	T1,TTYTAB##(J)	;CONTROLLING TTY
	CAIN	T1,(F)		;IS THIS IT?
	PJRST	OUTSTR		;YES, THEN TOPOUS IS SAME AS OUTSTR
	PUSHJ	P,SAVE4##	;SET TO JOIN OUTSTR CODE IN MIDDLE
	MOVEI	P3,TYO7W	;TYPEOUT ROUTINE
	PJRST	OUTST3		;JOIN OUTSTR

TOPOU1:	PUSHJ	P,SAVE4##	;SET TO JOIN OUTSTR CODE IN MIDDLE
	MOVEI	P3,CCTYO
	PJRST	OUTST3		;JOIN OUTSTR

;OUTPUT IMAGE CHAR

TOPOIC::AOS	(P)		;SKIP RETURN			
	JRST	IONEOU		;TYPE IT
;INPUT A CHAR ;⊗ TOPISC TOPINC TOPIIC TOPRES

TOPISC:	SKIPA	P1,[EXP INCHRW]
TOPINC:	MOVEI	P1,INCHWL
	AOS	(P)
	LDB	T1,PUUOAC##	;WHERE TO PUT ANSWER
	HRR	M,T1
	PUSHJ	P,TOPDDB
	  SETZB	F,S		;NO DDB, NO I/O STATUS
	PUSHJ	P,TYIEAT	;EAT ANY LEFT-OVER COMMAND
	PJUMPN	F,(P1)		;INPUT AND BLOCK IF A DDB AVAILABLE
	PUSHJ	P,TYI		;NO DDB, CAN'T BLOCK, GET CHAR
	  MOVEI	T3,0		;NONE THERE--RETURN NULL
	MOVE	T1,T3		;COPY CHAR
	JRST	STOTAC##	;STORE FOR USER

;INPUT IMAGE CHAR

TOPIIC==RTZER##

;DO A RESCAN

TOPRES:	PUSHJ	P,TRESCU	;DO IT
	  JRST	CPOPJ1##	;WIN
	JRST	CPOPJ1##	;WIN
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. I/O SUBROUTINES ;⊗ TOPDDB TOPDD2 TOPDD1

;GET A DDB FOR TRMOP. I/O

TOPDDB:	SETZ	S,		;IN CASE NO I/O STATUS AVAILABLE
	HRRZ	F,LDBDDB(U)	;GET DDB POINTER
	JUMPN	F,TOPDD2	;FIND A DDB?
	HRLZ	T2,LDBDCH(U)	;NO, GET THE LINE STATUS
	JUMPGE	T2,TOPDD2	;IS IT A PTY?
	LDB	T1,LDPLNO	;YES, GET THE TTY NUMBER
	HRRZ	F,PTYTAB##-PTYOFS##(T1)	;GET DDB ADDRESS, IF ANY
TOPDD2:	JUMPE	F,TOPDD1	;ANY DDB THERE?
	MOVE	S,DEVIOS(F)	;AH - A DDB, GET I/O STATUS
	LDB	T1,PJOBN##	;YES--IS IT MINE?
	CAMN	T1,.CPJOB##	; ..
	AOSA	(P)		;YES--USE IT
	SETZ	S,		;NO, THEN NO I/O STATUS AFTER ALL
	POPJ	P,		;RETURN AS APPROPRIATE

TOPDD1:	PUSHJ	P,TTYNAM	;GET SIXBIT NAME
	MOVE	T1,T2		;PUT IN T1
	PUSHJ	P,GETDDB	;GET A DDB
	  POPJ	P,		;NONE LEFT
	MOVEI	T1,ASSPRG	;INIT THE DDB SO
	IORM	T1,DEVMOD(F)	; IT WILL STICK
	MOVE	T1,.CPJOB##	; AROUND AND WE
	DPB	T1,PJOBN##	; CAN WAKE OWNER
	MOVE	S,DEVIOS(F)	;LOAD UP I/O STATUS WORD
	AOS	(P)		;SKIP RETURN (CALL?)
	PUSHJ	P,@0(P)		;CALL OUR CALLER
	  JRST	.+2		;NON-SKIP
	AOS	-1(P)		;SKIP
	PUSHJ	P,TTYREL	;KILL OFF DDB
	JRST	TPOPJ##		;AND RETURN
	SUBTTL	TTCALL AND TRMOP. -- TRMOP. DATASET FUNCTIONS ;⊗ TOPDSE TOPDSF TOPDF1 TOPDSS

IFN FTMODM,<
;MORE SUBROUTINES FOR TRMOP

TOPDSE:	MOVE	T1,LDBDCH(U)	;GET DEVICE CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE LINE
	JRST	[PUSHJ P,NETDSE	;LET NETSER DO IT
		 JRST CPOPJ1##]	;SKIP RETURN
>
	TRNN	T1,LDRDSD	;IS IT A DATASET?
	JRST	TOPX4		;NO. ERROR CODE 4
	LDB	U,LDPDSC	;GET THE TABLE OFFSET INTO U
	MOVSI	T1,DSCIC2	;CLEAR FAILURE, DIALLER FLAGS AND TIMER
	ANDCAM	T1,DSCTAB##(U)	; ..
	MOVSI	T1,DSCSWC	;SET TO ALLOW HIM ON
	PUSHJ	P,DSRRN1	;SEND TO MODEM HANDLER
	JRST	CPOPJ1##	;AND SKIP RETURN

TOPDSF:	MOVE	T1,LDBDCH(U)	;GET DEV CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE LINE
	JRST	[PUSHJ P,NETDSF	;YES, LET NETSER DO IT
		 JRST CPOPJ1##]	;SKIP RETURN
>
	TRNN	T1,LDRDSD	;IS IT A MODEM
	JRST	TOPX4		;NO. CAN'T DO THIS.
	PUSHJ	P,LDBCLR	;CLEAR OUT LDB
	HRRZ	F,LDBDDB(U)	;DDB?
	JUMPE	F,TOPDF1	;NOT CONTROLLING JOB
	MOVE	T1,DEVMOD(F)
	TLNN	T1,TTYATC	;CONTROLLING TTY?
	JRST	TOPDF1		;NOPE
	PUSHJ	P,DSCDET	;DETACH IT
TOPDF1:	LDB	U,LDPDSC	;GET TABLE INDEX
	MOVSI	T1,DSCHWC	;CLEAR
	ANDCAM	T1,DSCTAB##(U)
	PUSHJ	P,DSROF1	;HANG IT UP
	JRST	CPOPJ1##	;AND SKIP RETURN

TOPDSS:	MOVE	T1,LDBDCH(U)	;CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE?
	JRST	NETDSS		;YES, LET NETSER DO IT
>
	TRNN	T1,LDRDSD	;DATASET?
	JRST	TOPX4		;NO, LOSE
	LDB	U,LDPDSC	;DSCTAB OFFSET
	SKIPL	DSCTAB##(U)	;HARDWARE CARRIER?
	TDZA	T1,T1		;NO
	MOVSI	T1,DSCHWC	;YES
	JRST	STOTC1##	;STORE ANSWER FOR USER
IFE FTDIAL,< ;⊗ TOPDSC NETDSS NETDSE NETDSF NETDSC NETISR
	TOPDSC==CPOPJ##
>
IFN FTNET,<
	;CODE TO CONTROL REMOTE DATASET LINES
NETDSS:	MOVEI	T3,DSTSTS	;STATUS
	JRST	NETISR		;CALL NETSER
NETDSE:	MOVEI	T3,DSTON	;SET DATASET ON
	JRST	NETISR		;CALL NETSER
NETDSF:	MOVEI	T3,DSTOFF	;SET DATASET OFF
	JRST	NETISR		;CALL NETSER
NETDSC:	MOVEI	T3,DSTCRQ	;DIALER REQUEST
NETISR:	MOVEI	T1,ISRDSC	;DATASET CONTROL FUNCTION
	PJRST	D85DSC##	;CALL NETSER DIRECTLY SINCE NO DATASET TIMING
>
IFN FTDIAL,< ;⊗ TOPDSC TOPDC1 TOPDC2 TOPDC3
TOPDSC:
	MOVE	T1,LDBDCH(U)	;DEVICE CHARACTERISTICS
IFN FTNET,<
	TRNE	T1,LDRREM	;REMOTE LINE
	JRST	NETDSC		;YES
>
	TRNN	T1,LDRDSD	;DATASET?
	JRST	TOPX4		;NO. CAN'T DIAL THEN.
IFN FTMP,<
	PUSHJ	P,ONCPUL##	;MUST BE ON DEVICES OWN CPU
>
	LDB	U,LDPDSC	;GET DSCTAB INDEX
	MOVE	T1,DSCTAB##(U)	;AND BITS
	TLNE	T1,DSCHWC!DSCSWC	;ALREADY IN USE?
	JRST	TOPX5		;YES. CAN'T DIAL ON IT.
TOPDC1:	HRRZ	T1,DSCTAB##(U)	;GET TERMINAL NUMBER FOR MODEM
	CAME	T1,DSDUNI##	;BUSY FOR SAME UNIT, OR
	AOSN	TTYDDL##	;DIALLER FREE?
	JRST	TOPDC2		;YES
	MOVEI	T1,5		;NO. WAIT FOR IT.
	PUSHJ	P,SLEEP##	; ..
	JRST	TOPDC1		;TRY AGAIN
TOPDC2:	MOVEM	T1,DSDUNI##	;SAVE LINE BEING DIALLED
	PUSHJ	P,GETWRD##	;FROM USER CORE
	  JRST	TOPX3		;ADDRESS CHECK
	MOVEM	T1,DSCNUM	;STORE FOR DIALLER CODE
	HRRI	M,1(M)		;AND SECOND WORD
	PUSHJ	P,GETWRD##	; ..
	  JRST TOPX3		;ADDRESS CHECK
	TRO	T1,17		;GUARANTEE AN END OF NUMBER CODE
	MOVEM	T1,DSCNUM+1	;STORE SECOND WORD
	MOVSI	T1,DSCIC2	;CLEAR OUT THESE BITS
	ANDCAM	T1,DSCTAB##(U)	;IN CONTROL TABLE
	MOVSI	T1,DSCSWC!DSCDLW!↑D30
	IORM	T1,DSCTAB##(U)	;AND SET UP TO WAIT FOR DIALLER
	MOVE	T1,[POINT 4,DSCNUM]
	MOVEM	T1,TTYDDA##	;STORE INITIAL POINTER TO NUMBER
	MOVEI	T3,DSTCRQ	;CALL REQUEST CODE
	PUSHJ	P,DSCCAL	;TO THE DEVICE HANDLER
TOPDC3:	MOVEI	T1,↑D15		;SLEEP FOR FIFTEEN SECONDS
	PUSHJ	P,SLEEP##	; ..
	MOVE	T1,DSCTAB##(U)	;SEE WHAT HAPPENED.
	TLNE	T1,DSCDLF	;FAIL?
	JRST	TOPX5		;YES.
	TLNE	T1,DSCDLC	;COMPLETED OK?
	JRST	CPOPJ1##	;YES. SKIP RETURN TO USER
	JRST	TOPDC3		;NEITHER YET. LOOP.

> ;END OF FTDIAL
> ;END OF FTMODM
IFN FTCAFE!FTKS10,< ;⊗ TOPABR TOPELE

TOPABR:	MOVEI	T3,<LPCABR>B27	;SET UP FUNCTION
	MOVEI	T1,ISRLPC	;FUNCTION CODE
	SKIPGE	LDBISR(U)	;SKIP IF NOT DC76
	PUSHJ	P,@LDBISR(U)	;CALL SERVICE ROUTINE
	JRST	CPOPJ1##	;GIVE GOOD RETURN
>;IFN FTCAFE!FTKS10

;HERE TO SET TYPE ELEMENT IN 2741
IFN FT2741,<

;ASSUME THAT THE ELEMENT CAN BE SET.

TOPELE:	PUSHJ	P,GETWRD##	;GET SETTING.
	  JRST	TOPX3		;ADDRESS CHECK
	MOVE	T3,T1
	MOVEI	T1,ISRELE	;FUNCTION
	PUSHJ	P,@LDBISR(U)	;CALL ISR
	  JRST	TOPX2		;BAD NUMBER
	JRST	CPOPJ1##	;WIN
>;IFN FT2741
	SUBTTL	TTCALL AND TRMOP. -- TYPE INTO TTY ON BEHALF OF A USER ;⊗ TOPMTY TOPMT1 TOPMT2 TOPTYP TOPMT3

;	TOPMTY	TYPE A STRING ON BEHALF OF USER

;ADDR:	LINE NO.
;	[ASCIZ/STRING/]

TOPMTY:	PUSHJ	P,SAVE3##	;SAVE AN AC
	LDB	P1,LDPLNO	;LINE NUMBER
	PUSHJ	P,GETWRD##	;GET ADDRESS OF STRING
	  JRST	TOPX3		;ADDRESS CHECK
	HRRI	M,-1(T1)	;AND PUT IT IN M FOR FUTURE GETWD1'S
	HRROS	T1		;LEFT JUSTIFIED ASCIZ STRING
	PUSHJ	P,CKSTR##	;MAKE SURE ITS IN CORE AND LEGAL
	  JRST	TOPX3		;ADDRESS CHECK
	AOS	(P)		;GIVE GOOD RETURN

TOPMT1:	MOVE	P3,[POINT 7,P2]	;SET UP BYTE POINTER
	PUSHJ	P,GETWD1##	;GET NEXT WORD OF ASCIZ STRING
	MOVE	P2,T1		;AND SAVE IT
TOPMT2:	TLNN	P3,760000	;END OF CURRENT WORD?
	JRST	TOPMT1		;YES - GET NEXT ONE
	ILDB	T3,P3		;GET NEXT CHAR
	JUMPE	T3,PTSTRT	;END OF STRING, WAKE CONTROLLER
	MOVE	U,LINTAB##(P1)	;SET LDB ADDRESS
	PUSHJ	P,TOPTYP	;TYPE IT
	JRST	TOPMT2		;NEXT CHAR



;TOPTYP  --  TYPE ONE CHARACTER FOR USER
;CALL WITH CHARACTER IN T3, LDB IN U

TOPTYP::PUSHJ	P,PEVEN8	;COMPUTE THE PARITY
	MOVEI	T2,L1RMIF	;MIC INTERLOCK BIT
TOPMT3:	SCNOFF			;NO INTERRUPTS WHILE SETTING LOCK
	TDNE	T2,LDBBYT(U)	;CHECK INTERLOCK
	JRST	[SCNON		;ALLOW PENDING INTERRUPTS
		 JRST TOPMT3]	;TRY AGAIN
	IORM	T2,LDBBYT(U)	;SET THE INTERLOCK BIT
	SCNON			;AND ALLOW INTERRUPTS
	PUSHJ	P,RECINU	;GO AND TYPE IT
	MOVEI	T2,L1RMIF	;GET AND
	ANDCAB	T2,LDBBYT(U)	; CLEAR THE "MIC IS TYPING" FLAG
	POPJ	P,		;AND GO GET NEXT CHAR
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  SET/CLEAR LDBMIC ;⊗ TOPMCL TOPMST TOPMS1

IFN FTMIC, <
;	MICCLR - CLEAR DOWN LDBMIC
;ADDR:	LINE NO.

;	MICSET - SET UP LDBMIC
;ADDR:	LINE NO.
;	STATUS
;
;	BOTH GIVE OLD CONTENTS OF LDBMIC IN ADDR+1

TOPMCL:	MOVEI	T1,LDRPTY	;A PTY?
	TDNE	T1,LDBDCH(U)
	PUSHJ	P,PTYOW##	;YES, TELL BATCON
	SETZ	T1,		;SET IMPLIED ZERO ARGUMENT
	JRST	TOPMS1		;JOIN MIC SET CODE

TOPMST:	PUSHJ	P,GETWRD##	;GET THE ARGUMENT
	  JRST	TOPX3		;ADDRESS CHECK
	PUSH	P,T1
	ANDI	T1,177
	CAMLE	T1,HIGHJB##	;ISOLATE JOB NUMBER
	  JRST	[POP P,T1
		 PJRST ECOD2##]	;RETURN ERROR CODE 2 (OUT OF RANGE)
	POP	P,T1
	TLZ	T1,LDLMTI!LDLMMM;CLEAR INTERNAL BITS
TOPMS1:	MOVSI	T2,LDLMIC	;GET THE MIC ACTIVE BIT
	SKIPE	T1		;...
	IORM	T2,LDBDCH(U)	; SET OR
	SKIPN	T1		;...
	ANDCAM	T2,LDBDCH(U)	; CLEAR AS NEEDED
	EXCH	T1,LDBMIC(U)	;SET NEW VALUE, RETURN OLD
	AOS	(P)		;GOOD RETURN
	PJRST	PUTWDU##	;GIVE USER OLD MIC WORD
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  RETURN MIC STATUS ;⊗ TOPMGT TOPMG1

;	MICGET - GET STATUS
;ADDR:	LINE
;	RETURN RESULT TO ADDR+1

TOPMGT:	PUSHJ	P,SAVE1##	;SAVE AN AC
	SKIPN	P1,LDBMIC(U)	;IS MIC RUNNING US?
	JRST	TOPMG1		;NO FAIL RETURN
	HRRZ	F,LDBDDB(U)	;SET UP F
	JUMPE	F,TOPMG1	;ZERO MEANS HE LOGGED OUT -LOOSE HIM
	LDB	J,PJOBN##	;OTHERWISE - GET HIS JOB NO
IFN FTMP,<
	CAMN	J,COMJOB##	;ON THE SAME CPU AS US
	PUSHJ	P,ONCPU0##	;NO, GET HIM THERE
>
	PUSHJ	P,UJBSTX##	;GO GET JBTSTS
	TLZ	P1,LDLMMM!LDLMTI!LDLCL1	;CLEAR VOLATILE BITS
	TLNE	T1,(1B2)	;IN MONITOR MODE?
	TLO	P1,LDLCHK!LDLMMM;YES - SET FLAGS
IFN FTCIMP,<			;[arpa]
	SKIPE	LDBIMP(U)	;[arpa] XPATCHED?
	  PUSHJ	P,MICIMP##	;[arpa] YES, SEE IF CONNECTION CAN EAT MORE
>				;[arpa]
	TLNE	T1,(1B4)	;READY FOR I/P?
	TLO	P1,LDLCHK!LDLMTI;YES - SET FLAGS
IFN FTMLOG,<
	HRRZ	T1,LDBLOC(U)
	SKIPE	T1
	TLO	P1,LDLCHK!LDLCL1;SET TO FLAG
> ;END OF FTMLOG CONDITIONAL
	SKIPGE	LDBDDB(U)	;COMMAND WAITING?
	TLZ	P1,LDLMTI	;YES - CLEAR TI BIT
	MOVE	T1,P1		;PUT LDBMIC INTO T1 FOR
	AOS	(P)		;GOOD RETURN
	PJRST	PUTWDU##	;RETURNING TO USER

TOPMG1:	MOVSI	T1,LDLMIC	;THE CONTROLLED-BY-MIC BIT
	ANDCAM	T1,LDBDCH(U)	;CLEAR FOR XMTCHR
	SETZB	T1,LDBMIC(U)	;CLEAR DOWN LDBMIC
	PJRST	PUTWDU##	;AND EXIT
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  READ ERROR RESPONSE TEXT ;⊗ TOPMRS TOPMR1 TOPMR2 TOPMR3

;	MICRSP : RECORD ERROR MESSAGE
;ADDR:	LINE NO.
;	ADDRESS OF SPACE TO RETRIEVE RESPONSE

TOPMRS:	SKIPE	T2,LDBMIC(U)	;RUNNING MIC
	TLNN	T2,LDLERC	;ERROR?
	JRST	TOPX4		;NO
	TLNN	T2,LDLRSY	;MAKE SURE GOT TO INT LEVEL WITH SYNC
	JRST	TOPX4		;NO

	PUSHJ	P,GETWRD##	;GET ADDRESS OF RESPONSE BUFFER
	  JRST	TOPX3		;ADDRESS CHECK
	PUSHJ	P,MICADC
	  JRST	TOPX3		;ADDRESS CHECK OF BUFFER
	PUSHJ	P,SAVE3##	;SAVE WORKING ACS
	MOVSI	P1,(<POINT 7,>)
	ADDI	P1,(T1)
	MOVEI	P2,<21*5>-1	;MAX SPACE IN BUFFER
	CAMLE	P2,LDBTOC(U)	;GOT THIS MANY?
	MOVE	P2,LDBTOC(U)	;NO - USE LESSER
	JUMPLE	P2,TOPX4	;NO CHARACTERS
	SKIPN	P3,LDBTOT(U)	;GET CHAR ADDRESS OF ERROR LINE
	JRST	TOPX4		;HASN'T GOT ONE?

TOPMR1:	LDCHK	T3,P3		;GET NEXT CHARACTER
TOPMR2:	EXCTUU	<IDPB T3,P1>
	JUMPE	T3,TOPMR3	;EXIT HAVING MADE ASCIZ
	SOJG	P2,TOPMR1	;GET NEXT CHAR
	SETZ	T3,		;MAKE ASCIZ
	JRST	TOPMR2

TOPMR3:	MOVSI	T1,LDLRSP!LDLRSY;CLEAR RESPONSE FLAG
	ANDCAM	T1,LDBMIC(U)
	AOS	(P)		;GOOD RETURN TO THE USER
	PJRST	TOPOKE		;START UP TERMINAL OUTPUT - GOOD EXIT
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  LOG ALL TERMINAL OUTPUT ;⊗ TOPMLG TOPML1 TOPML3 TOPML2

IFN FTMLOG,<

;	MICLOG: RECORD ALL UUO LEVEL OUTPUT
;ADDR:	LINE NUMBER
;	ADDR LOG BUFFER

TOPMLG:	SKIPE	T2,LDBMIC(U)	;RUNNING MIC?
	TLNN	T2,LDLLOG	;WANT LOG FEATURE?
	JRST	TOPX4

	PUSHJ	P,GETWRD##
	  JRST	TOPX3		;ADDRESS CHECK
	PUSHJ	P,MICADC	;ADDRRESS CHECK ALL OF BUFFER
	  JRST	TOPX3		;ADDRESS CHECK
	AOS	(P)		;SET FOR GOOD RETURN TO THE USER
	PUSHJ	P,SAVE2##	;SAVE WORKING ACS
	MOVSI	P1,440700
	HRRI	P1,(T1)
	MOVEI	P2,<21*5>-1

TOPML1:	SCNOFF			;DOWN PI SYSTEM
	SOSGE	LDBLOC(U)	;CHECK COUNT
	JRST	[SETZB T3,LDBLOC(U) ;FIX COUNT
		 JRST TOPML3]	;JOIN PROCESSING
	LDCHKR	T3,LDBLOT(U)	;TAKE A BYTE
TOPML3:	SCNON			;TURN PI'S BACK ON
TOPML2:	EXCTUU	<IDPB T3,P1>
	JUMPE	T3,XMTWAK
	SOJG	P2,TOPML1
	SETZ	T3,
	JRST	TOPML2		;LOOP UNTIL COUNT EXHAUSTED OR END BUFFER
> ;END OF FTMLOG CONDITIONAL
;STILL IN IFN FTMIC
	SUBTTL	TTCALL AND TRMOP.  --  MIC  --  MISCELLANEOUS MIC SUBROUTINES ;⊗ MICLGC MICLG1 MICLG2 MICADC MICAD1

IFN FTMLOG,<

; HERE WITH SCANNER INTERRUPTS DISABLED

MICLGC:	MOVE	T1,LDBMIC(U)	;GET MIC STATUS
	TLNN	T1,LDLLOG	;LOGGING?
	JRST	MICLG1		;NO-MIC HAS GIVEN UP MUST TIDY

	MOVE	T1,LDBTOP(U)	;MOVE TAKER TO PUTTER
	MOVEM	T1,LDBTOT(U)	;SO MIC CAN CATCH UP WITH PUTPUT
	MOVE	T1,LDBTOC(U)	;REMEMBER HOW MANY
	ADDM	T1,LDBLOC(U)	;KEEP TRACK FOR MIC
	JRST	MICLG2
;MIC HAS GONE AWAY MUST TIDY UP LOG BUFFER

MICLG1:	MOVE	T1,LDBLOT(U)	;MOVE PUTTER AND TAKER
	MOVEM	T1,LDBTOT(U)
	MOVEM	T1,LDBTOP(U)	;BACK UP
	SETZM	LDBLOT(U)	;ZAP LOG BUFFER
MICLG2:	SETZM	LDBTOC(U)	;ZAP COUNT
	JRST	SONPPJ		;AND EXIT
> ;END OF FTMLOG CONDITIONAL
;STILL IN IFN FTMIC

;SUBROUTINE TO ADDRESS CHECK A USER BUFFER

MICADC:	PUSH	P,M
	PUSH	P,T1
	HRRI	M,(T1)
	PUSHJ	P,GETWRD##
	  JRST	MICAD1
	HRRI	M,21(M)
	PUSHJ	P,GETWRD##
	TRNA
	AOS	-2(P)
MICAD1:	POP	P,T1
	JRST	MPOPJ##
;STILL FTMIC ;⊗ MICPOS MICPS1 MICPS2 MICPS4 MICPS3

;SUBROUTINE TO SET UP HORIZONTAL POSITION FOR MIC AND TO CHECK FOR
;OPERATOR AND ERROR CHARS IN COLUMN 1

MICPOS:	SKIPN	T2,LDBMIC(U)	;MIC RUNNING FOR THIS LINE?
	POPJ	P,		;NO, RETURN IMMEDIATELY
	PUSH	P,T3		;PRESERVE CHAR
	ANDI	T3,177		;MASK OFF PARITY
	PUSHJ	P,SPCHEK	;GET CHARACTERISTICS OF CHAR
	  JRST	MICPS2		;NOT SPECIAL
	TLNN	T1,CHCRET	;IS IT <CR>?
	JRST	MICPS1		;NOT - MUST CHECK OTHERS
	TLO	T2,LDLCL1	;SET COL 1 FLAG IN MICLDB
	MOVEM	T2,LDBMIC(U)
	JRST	T3POPJ##	;AND RETURN

MICPS1:	CAIE	T3,177		;IS IT A RUBOUT
	CAIN	T3,12		;OR LINE-FEED
	JRST	T3POPJ##	;YES - NO CHECKING
MICPS2:	TLZN	T2,LDLCL1	;ARE WE IN COLUMN 1?
	JRST	T3POPJ##	;NO - RETURN
	LDB	T1,LDP.OP	;GET OPERATOR CHAR
	JUMPE	T1,MICPS4	;JUMP IF NOT SET
	CAMN	T1,T3		;HAVE WE FOUND ONE?
	TLO	T2,LDLCHK!LDLOPC;YES - SET BITS
MICPS4:	LDB	T1,LDP.ER	;GET ERROR CHAR
	JUMPE	T1,MICPS3	;IF NO ERROR
	CAIE	T3,"?"		;"?" ERROR CHARACTER
	CAMN	T1,T3		;ONE OF THOSE?
	TLO	T2,LDLCHK!LDLERC;YES - SET ITS FLAGS
MICPS3:	MOVEM	T2,LDBMIC(U)	;STORE MIC WORD
	JRST	T3POPJ##	;RESTORE T3, AND RETURN
;STILL IN IFN FTMIC



;STILL FTMIC ;⊗ MLOGOF MICWAK MICWA1 MICECH MICRIC MICPRC

IFN FTMLOG,<
;A ROUTINE TO FREE THE MIC LOG BUFFER IF REQUIRED

MLOGOF:	SKIPN	LDBLOT(U)	;HAS NOT GOT ONE
	POPJ	P,0
	SCNOFF			;SNEAKY PEEK
	SKIPE	LDBTOC(U)	;OUTPUT BUFFER IDLE
	JRST	SONPPJ		;NO FORGET IT
	JRST	MICLG1		;YES-GO ZAP LOG BUFFER AND TURN ON PI
> ;END OF FTMLOG CONDITIONAL

;ROUTINE TO WAKE MIC UP WHEN CONTROLLED JOB REQUIRES INPUT
MICWAK:	LDB	T1,LDPMJN	;LOAD MASTER JOB NO.
	CAMLE	T1,HIGHJB##	;JOB NUMBER TOO BIG?
	  JRST	MICWA1		;YES JUST RETURN
	MOVE	T2,JBTSTS##(T1)	;CHECK JOB STATUS
	TLNN	T2,JLOG		;LOGGED IN?
	  JRST	MICWA1		;NO JUST RETURN
	PUSHJ	P,WAKJOB##	;GO WAKE MIC
MICWA1:	MOVE	T1,LDBDCH(U)	;RESTORE C(U)
	POPJ	P,		;AND RETURN

MICECH:	TLNN	T1,CHCRET	;IS IT A <CR>?
	POPJ	P,		;NO, RETURN
	PUSH	P,T1		;SAVE T1
	MOVSI	T1,LDLCL1	;YES, SET COL 1 BIT
	IORM	T1,LDBMIC(U)	; IN LDBMIC
	JRST	TPOPJ##		;RETURN

MICRIC:	CONSO	PI,PI.IPA	;AT INTERRUPT LEVEL?
	POPJ	P,		;NO, THEN MIC TYPED IT
MICPRC:	CAIE	T3,1		;IS THE CHAR A ↑A
	CAIN	T3,201		;WITH POSSIBLE PARITY?
	JRST	MICRIA		;YES - GO DEAL WITH ↑A
	TLO	T1,LDLCHK!LDLMCC;SAY THAT ↑C WAS TYPED
	MOVEM	T1,LDBMIC(U)	;PUT IT BACK
	POPJ	P,		;AND RETURN
;STILL FTMIC ;⊗ MICRIA PTYMCK FRCSET

MICRIA:	TLO	T1,LDLCHK!LDLMCA;SAY ↑A
	MOVEM	T1,LDBMIC(U)	;PUT IT AWAY!
	TRC	T3,202		;CONVERT CHAR INTO A ↑C
	MOVSI	T1,CHBRK!CHCRE!CHCNC
	IORM	T1,-1(P)	;AND SET UP BITS TO LOOK LIKE ↑C
	POPJ	P,

PTYMCK:	CAIN	T3,20
	TLO	T2,LDLCHK!LDLMCP
	CAIN	T3,2
	TLO	T2,LDLCHK!LDLMCB
	MOVEM	T2,LDBMIC(U)
	TLNE	T2,LDLMCP!LDLMCB
	JRST	RICB3
	JRST	PTYPT1
> ;END IFN FTMIC

;CO-ROUTINE TO SETUP U AND .CPTOA SO THAT THE MONITOR CAN TYPE
; A COMMAND AT ITSELF.  USES LDB CORRESPONDING TO FRCLIN

FRCSET::EXCH	U,(P)		;GET CALLER'S PC, SAVE U
	PUSH	P,.CPTOA##	;SAVE .CPTOA
	MOVEM	U,1(P)		;WHERE TO RETURN TO CALLER
	MOVEI	U,TOPTYP	;PUT CHARS INTO INPUT
	MOVEM	U,.CPTOA##	; STREAM
	MOVE	U,LINTAB##+FRCLIN## ;LDB
	PUSHJ	P,@1(P)		;CALL CALLER AS A SUBROUTINE
	  CAIA			;NON-SKIP
	AOS	-2(P)		;PROPAGATE SKIP
	POP	P,.CPTOA##	;RESTORE .CPTOA
	JRST	UPOPJ##		;RESTORE U AND RETURN
	SUBTTL	SUBROUTINES FOR I/O ;⊗ TYIS TYI TYICC TYICC2 TYICC3 TYICC4

;SUBROUTINE TO READ A CHARACTER AND KEEP THE BREAK COUNT RIGHT
;
;IT IS ASSUMED THAT THE CALLER HAS DONE ANY NECESSARY WAITING. THERE
;ARE TWO UNUSUAL CASES: FIRST, IF THERE ARE NO CHARACTERS IN THE
;BUFFER, TYI WILL NON-SKIP RETURN. IF THE CHARACTER READ IS A
;CONTROL C, AND IF THE TERMINAL IS IN USER MODE, NOT SLAVED, NOT
;IN IMAGE INPUT STATE, AND NOT RUNNING UNDER JACCT, THEN TYI CALLS
;ROUTINES TO PUT CONSOLE AT MONITOR LEVEL, AND GOES BACK INTO I/O
;WAIT UNTIL A POSSIBLE CONTINUE COMMAND.
;
;IT IS THE CALLER'S RESPONSIBILITY TO EAT ANY POSSIBLE COMMAND LEFT
;LYING AROUND (I.E., CALL TYIEAT).
;
;TYICC USES P3! BE WARNED!

TYIS:	PUSHJ	P,SAVE3##	;REALLY SHOULD DO IT
	SETOM	P3		;FLAG DON'T WAIT IF NOTHING THERE
	JRST	TYICC2

TYI:	PUSHJ	P,SAVE3##
	TDZA	P3,P3		;FLAG WAIT ON ↑C, CONTINUE
TYICC:	TDZA	P3,P3		;FLAG WAIT ON ↑C, CONTINUE SEQUENCE
TYICC2:	SETZB	P1,P2		;INDICATE NO BUFFER
TYICC3:	TRNE	S,IODERR	;HAS HE GOTTEN A ↑C?
	POPJ	P,		;YES, FORGET IT
TYICC4:	SCNOFF			;NO RACES
	SOSGE	LDBTIC(U)	;ANY LEFT TO INPUT?
	JRST	TYICCZ		;FIX INPUT COUNT AND RESTORE PI
	LDCHKR	T3,LDBTIT(U)	;GET CHARACTER
	MOVE	T2,LDBTIT(U)	;INPUT TAKER POINTER
	CAMN	T2,LDBBKU(U)	;TAKEN LAST BREAK?
	SETZM	LDBBKU(U)	;YES, ZAP POINTER TO IT
	SCNON			;ALLOW INTERRUPTS
	PUSH	P,T3		;PRESERVE CHAR.
	SKIPG	LDBTIC(U)	;IS THIS THE LAST CHARACTER IN THE BUFFER
	PUSHJ	P,CHKXON	;YES, GO CHECK IF XON IS NEEDED
	POP	P,T3		;RESTORE CHAR.
	TRNE	T3,400		;IMAGE CHARACTER?
	JRST	CPOPJ1##	;YES, DONE HERE

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ TYIC TYICCZ

TYIC:
IFN FTCIMP,<			;[arpa]
	SKIPN	LDBIMP(U)	;[arpa] NO FURTHER PROCESSING IF XPATCHED
>				;[arpa]
	PUSHJ	P,SPCHEK	;SEE WHAT KIND OF CHARACTER IT IS
	  JRST	CPOPJ1##	;NOTHING SPECIAL
	JUMPE	T3,TYICC4	;IF NULL, SKIP IT.
	TLNE	T1,CHALT	;SOME ALT CHAR?
	TLNE	U,LDLFCS	;FULL CHR SET?
	CAIA			;NO CONVERSION
	PUSHJ	P,RIALTO	;CONVERT
	TLNE	T1,CHBRK	;BREAK CHARACTER?
	SOS	LDBBKC(U)	;YES. COUNT IT DOWN.
	JUMPE	F,CPOPJ1##	;GOOD RETURN IF NO DDB
	TLNN	T1,CHCNC	;CONTROL C CHARACTER?
	JRST	CPOPJ1##	;NO JUST RETURN TO CALLER
	MOVE	T1,DEVMOD(F)	;GET SOME BITS
	TLNN	T1,TTYATC	;IS TTY CONTROLLING A JOB?
	JRST	CPOPJ1##	;NO, RETURN CHAR
	HLL	U,LDBDCH(U)	;GET LINE STATE FLAGS
	PUSHJ	P,CNCCHK	;SEE IF IT IS A CONTROL C
	  JFCL			;YES, STORE
	  JRST	CPOPJ1##	;YES, BUT IT SHOULD BE STORED.
	MOVE	S,[XWD	IOW,IOACT]
	IORB	S,DEVIOS(F)
	SKIPN	P3		;WAIT?
	PUSHJ	P,TIWAIT	;NOW WAIT IN CASE TYPE CONTINUE
	PUSHJ	P,TYIEAT	;EAT THE CONTINUE COMMAND
	JUMPE	P1,TYICC3	;DONE IF NO PTR
	DMOVE	T1,P1		;SETUP BYTE POINTER AND COUNT SO PRNGE CAN
	PUSHJ	P,PRNGE##	;MAKE SURE BUFFER DIDN'T GO AWAY
				; (USER TYPED .CORE <SMALLER-VALUE> AND
				;  ZAPPED THE END OF HIS BUFFER)
	JRST	TYICC3		;LOOP AROUND AGAIN.


;HERE WITH THE PI SYSTEM TURNED OFF AFTER INPUT COUNT HAS BEEN
;FOUND EXHAUSTED.  (PROBABLY BY A SOSGE THAT DID NOT SKIP).

TYICCZ:	SETZM	LDBTIC(U)	;FIX CHARACTER COUNT
	SETZM	LDBBKU(U)	;CLEAR BREAK POSITION
	SETZM	LDBBKC(U)	; AND COUNT, SINCE EMPTY
	JRST	SONPPJ		;RESTORE PI AND NON-SKIP RETURN
;SUBROUTINE TO DISCARD A COMMAND FROM INPUT BUFFER IF L2RECS STILL ON ;⊗ TYIEAT TYIL TYID

TYIEAT:	MOVEI	T1,L2RECS	;GET EAT CHARACTER SYNC BIT
	TDNN	T1,LDBBY2(U)	;STILL WANT COMMAND EATEN?
	POPJ	P,0		;NO. RETURN.
TYIL:	SCNOFF			;NO RACES
	SOSGE	LDBTIC(U)	;ANY CHARACTERS LEFT?
	JRST	[SETZM	LDBTIC(U)	;FIX COUNT
		SCNON		;LET WORLD BACK IN
		JRST	TYID]	; AND GIVE UP
	LDCHKR	T3,LDBTIT(U)	;TAKE A CHARACTER
	MOVE	T2,LDBTIT(U)
	CAMN	T2,LDBBKU(U)	;TAKEN LAST BREAK?
	SETZM	LDBBKU(U)	;ZAP POINTER
	SCNON			;ALLOW INTERRUPTS
	PUSHJ	P,SPCHEK	;GET CHARACTER DESCRIPTORS
	  JRST TYIL		;ORDINARY
	TLNE	T1,CHBRK	;BREAK CHAR?
	SOSA	LDBBKC(U)	;YES. COUNT IT AND QUIT
	JUMPN	T3,TYIL		;NO. LOOP IF STILL SOME TO GO
TYID:	MOVEI	T1,L2RECS	;NOW CLEAR THE BIT
	ANDCAM	T1,LDBBY2(U)	;IN THE DEVICE WORD
	POPJ	P,0
;HERE ARE THE ROUTINES TO PERFROM VARIOUS "TTY INPUT" FUNCTIONS ;⊗ CTIGNC CTIGLC CTISLC CTIGBP CTISBP CTICOM COMTIV CCTYI CCTYI1

CTIGNC::PUSHJ	P,CTICOM	;GET THE NEXT CHARACTER (IN T3)
CTIGLC::PUSHJ	P,CTICOM	;GET THE "LAST CHAR COMCON READ" (IN T3)
CTISLC::PUSHJ	P,CTICOM	;SET THE "LAST CHAR" (FROM T3)
CTIGBP::PUSHJ	P,CTICOM	;GET THE BYTE POINTER BEING USED (IN T1)
CTISBP::PUSHJ	P,CTICOM	;SET THE BYTE POINTER TO USE (FROM T1)

CTICOM:	EXCH	T4,(P)		;SAVE "T4" GET OFFSET
	ANDI	T4,-1		;GET JUST THE ADDRESS
	SUBI	T4,CTIGNC+1	;MAKE IT 0 ORIGIONED
	ADD	T4,.CPTIV##	;GET ADDRESS OF TTY INPUT VECTOR TO USE
	XCT	(T4)		;CALL EITHER COMCON OR ONCE
	POP	P,T4		;RESTORE T4
	POPJ	P,		;  AND RETURN

;HERE IS THE "NORMAL" TTY INPUT VECTOR
COMTIV::PUSHJ	P,CCTYI		;CCTYI GET'S NEXT CHAR
	LDB	T3,LDPLCH	;LAST CHAR IS HERE
	DPB	T3,LDPLCH	; STILL HERE...
	MOVE	T1,LDBCLP(U)	;BYTE POINTER IS HERE
	MOVEM	T1,LDBCLP(U)	; STILL HERE...

;ROUTINE TO "GET NEXT CHAR" FROM NORMAL LINES
CCTYI::	SCNOFF			;NO RACES
	SKIPE	T2,LDBCLP(U)	;ADDRESS THERE TO USE?
	CAMN	T2,LDBTIP(U)	;YES. CAUGHT UP TO PUTTER?
	JRST	CCTYI1		;YES.  RETURN END OF LINE CHARACTER
	LDCHK	T3,LDBCLP(U)	;LOAD CHARACTER FROM TTCMCA POINTER
	JRST	SONPPJ		;ALLOW INTERRUPTS AND RETURN

CCTYI1:	MOVEI	T3,12		;RETURN BREAK CHAR
	JRST	SONPPJ
;SUBROUTINE TO SEE IF A CONTROL C SHOULD BE ACTED ON OR STORED. ;⊗ CNCCHK CNCCK1 CLRIIQ CLRIMI CLRIM1
;NON-SKIP MEANS STORE IT.
;SKIP MEANS JACCT SET
;DOUBLE SKIP MEANS .HALT DONE.

CNCCHK:	TLNE	U,LDLSLV+LDLIMI	;SHOULD ↑C BE RETURNED?
	POPJ	P,0		;YES.
	AOS	(P)		;ADVANCE RETURN
	PUSH	P,T1		;MAYBE NOT. SAVE T1.
	HRRZ	F,LDBDDB(U)	;GET LINE'S JOB
	JUMPE	F,CNCCK1	;IF NO DDB ATTACHED, ASSUME SHOULD DO ↑C
	LDB	T1,PJOBN##	; ..
	MOVE	T1,JBTSTS##(T1)	;GET JOB STATUS WORD
	TDNE	T1,[XWD JACCT,JS.DEP]	;IS ↑C LEGAL? (PRIVILEGED PROG OR
				; DAEMON ERROR PAUSE)
	JRST	TPOPJ##		;NO. GIVE IT TO CUSP

	PUSHJ	P,CNCMOD
CNCCK1:	PUSHJ	P,TTHALT	;FORCE CONTROL C
	JRST	TPOPJ1##	;RESTORE T1, SKIP RETURN

CLRIIQ:	HRRZ	F,LDBDDB(U)	;GET DDB, IF ANY.
	JUMPE	F,CLRIM1	;CLEAR BIT IF NO DDB
	MOVE	S,DEVIOS(F)	;GET STATUS WORD.
	TRNE	S,I		;IF STILL IMAGE, DON'T CLEAR BIT
	POPJ	P,0		;IMAGE. JUST RETURN
CLRIMI:	HRRZ	F,LDBDDB(U)	;GET ATTACHED JOB, IF ANY
	JUMPE	F,CLRIM1	;IF NONE, SKIP PART OF THIS
	MOVSI	S,FRCEND	;ALSO CLEAR FORCED END OF FILE BIT
	ANDCAB	S,DEVIOS(F)
CLRIM1:	MOVSI	T1,LDLIMI	;NO. CLEAR IMAGE BIT AND TIME
	DPB	T1,LDPTIM	; ..
	ANDCAM	T1,LDBDCH(U)	; ..
	PJRST	SETCHP		;TELL THE FRONT END AND RETURN
;ROUTINE TO PUT TERMINAL INTO MONITOR COMMAND MODE. DON'T CALL THIS ;⊗ CNCMOD CNCMO2 COMQ
;ROUTINE IF TERMINAL IS A SLAVE, UNLESS YOU WANT SLAVE BIT CLEARED TOO.
;CALL WITH LINE SET.

CNCMOD::
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR PAGE COUNTER
	PUSHJ	P,STRTDL	;LET ONE DEFERRED LINE ECHO
	MOVEI	T1,L2RECS	;EAT RACE SYNC BIT
	ANDCAM	T1,LDBBY2(U)
	HRRZ	T1,LDBDDB(U)	;DDB ADDRESS
	JUMPE	T1,CNCMO2	;IF NO DDB, DON'T TRY TO TOUCH IT
	MOVEI	T2,PIMMOD	;MAKE SURE THAT PIMMOD
	ANDCAM	T2,DEVIOS(T1)	;ISN'T SET IN THE DDB
	MOVSI	T2,LDLBKA	;THE VOLATILE BREAK-ON-ALL-CHARACTERS BIT
	TDNN	T2,LDBDCH(U)	;IN CHARACTER MODE?
	TDZA	T2,T2		;NO
	MOVSI	T2,IOLBKA	;YES, REMEMBER THAT FACT
	IORM	T2,DEVIOS(T1)	;FOR TTYUSR TO FIND LATER
CNCMO2:	MOVE	T1,[LDLIMI+LDLNEC+LDLDLR+LDLBKA+LDLPIM,,LDROSU]
	ANDCAM	T1,LDBDCH(U)	;CLEAR ALL THESE BITS
	MOVSI	T1,LDLCOM	;AND SET THIS ONE
	IORB	T1,LDBDCH(U)	; ..
	TRNE	T1,LDRPTY	;IS THIS LINE PTY-DRIVEN?
	PUSHJ	P,PTMNMD##	;YES. TELL PTYSER ABOUT IT.
	PUSHJ	P,SETCHP	;BE SURE REMOTES ARE INFORMED
	PJRST	NOCTRO		;CLEAR ↑O AND RETURN


;SUBROUTINE TO SKIP IF TERMINAL IS AT COMMAND LEVEL AND NOT SLAVED

COMQ:	SKIPGE	LDBDDB(U)	;LDBCMR ON?
	JRST	CPOPJ1##	;YES. ASSUME COMMAND LEVEL
	HLL	U,LDBDCH(U)	;GET LINE STATE
	TLNE	U,LDLCOM	;AT TOP LEVEL?
	TLNE	U,LDLSLV	;AND NOT SLAVED?
	POPJ	P,0		;NO. JUST RETURN
	HRRZ	F,LDBDDB(U)	;IS LINE ATTACHED TO A JOB?
	JUMPE	F,CPOPJ1##	;JUMP IF NOT
	PUSH	P,T1		;SAVE AN AC
	MOVE	T1,DEVMOD(F)	;GET DEVICE ASSIGN BITS
	TLNE	T1,TTYATC	;ATTACHED TO JOB?
	JRST	TPOPJ1##	;YES. SKIP RETURN
	LDB	T1,PJOBN##	;IS JOB NUMBER ZERO?
	JUMPE	T1,TPOPJ1##	;IF SO,SKIP RETURN
	JRST	TPOPJ##		;IF NOT ATTACHED, CAN'T DO COMMAND
;ROUTINE TO MAKE THIS TERMINAL VISIBLE TO COMMAND DECODER, IF AT COM LEVEL ;⊗ COMSET COMST1 COMSTF CMDSET CMDCLR
;CALL WITH LINE SET UP

COMSET::PUSHJ	P,COMQ		;IS LINE AT COMMAND LEVEL?
	  POPJ	P,0		;NO. JUST RETURN
IFN	FTTVP,<PUSHJ P,CLRPCT>	;CLEAR PAGE COUNTER
	MOVSI	T1,LDBCMR	;OK. SET REQUEST BIT
COMST1:	SCNOFF			;CAN'T LOOK AT LDBDDB(U) HERE
COMSTF::SKIPL	LDBDDB(U)	;WAS COMMAND REQUEST ON?
	AOS	COMCNT##	;NO. WAKE COMCON
	IORM	T1,LDBDDB(U)	;SET THE BITS IN LDBDDB(U)
	SCNON			;FALL INTO CMDSET

;SUBROUTINE TO SET/CLEAR BIT IN COMMAND MAP

CMDSET::SKIPA	T1,[IORM T3,CMDMAP##(T2)]
CMDCLR::MOVE	T1,[ANDCAM T3,CMDMAP##(T2)]
	PUSH	P,T3		;SAVE T3
	SETZM	T3
	LDB	T2,LDPLNO	;GET LINE #
	LSHC	T2,-5		;SET TO WORD ADDRESS
	ROT	T3,5		;BIT WITHIN WORD
	MOVE	T3,BITTBL##(T3)	;GET THE BIT
	XCT	T1		;SET OR CLEAR
	PJRST	T3POPJ##	;RETURN
TTFCOM::				;FORCED COMMAND TABLE ;⊗ TTFCOM TTFCXC TTFCXD TTFCXH TTFCXR TTFCXK TTFCXI TTFCXJ TTFCXU TTFCXT TTFCXW TTFCXL TTFCXS TTFCXF TTFCXG TTFCXX TTFCML MTTFCM
PHASE 0
TTFCXC:!SIXBIT /.HALT/			;CONTROL C
IFN FTMODM!FtCImp,<			;[arpa] needed for arpanet, too.
TTFCXD::!SIXBIT /.BYE/			;DATAPHONE DISCONNECT
TTFCXH::!SIXBIT /.HELLO/		;DATAPHONE CONNECT
>
TTFCXR::!SIXBIT /.RESTA/		;SYSTEM RESTART
TTFCXK:!SIXBIT /KJOB/			;FORCED KILL JOB
TTFCXI::!SIXBIT /INITIA/		;INITIALIZING CUSP CALL

IFN FTJCON,<
TTFCXJ::!SIXBIT /.FCONT/		;FORCED CONTINUE
>
IFN FTDAEM,<
TTFCXU::!SIXBIT /.DUMP/			;CCL RUN OF DUMP
>
TTFCXT:!SIXBIT	/.TYPE/			;RETYPE LINE
IFN FTWATCH,<
TTFCXW:!SIXBIT	/USESTA/		;1 LINE SYSTAT
>
IFN FTNET,<
TTFCXL::!SIXBIT	/.NETLD/		;AUTO DOWN LINE LOAD OF DAS80'S SERIES.
>
TTFCXS:!SIXBIT	/HALT/			;STOP JOB REGARDLESS OF ↑C TRAPPING

IFN FTCIMP,<				;[arpa]
TTFCXF::!SIXBIT	/.FTPSV/		;[arpa] run the FTP SERVER
TTFCXG::!SIXBIT	/FINGER/		;[arpa] SUPPORT A FINGER SERVER
>					;[arpa]


IFN FTPATT,<
TTFCXX:!SIXBIT /CTEST/			;FOR PATCHING
>
DEPHASE
TTFCML==:.-TTFCOM
MTTFCM==:-TTFCML				;MINUS LENGTH OF FORCED COMMAND TABLE
IFG TTFCML -20,<PRINTX ?TOO MANY FORCED COMMANDS!>
	SUBTTL	COMMAND LEVEL ROUTINES ;⊗ TTYCOM TTYCM0 TTYCM1 TTYCM2 TTYCM3 TTYCM4 TTCM4A TRESCN TRESC1

;ROUTINE TO SET UP TO READ A COMMAND FROM ANY REQUESTING LINE
;CALL FROM CLOCK LEVEL:
;	PUSHJ P,TTYCOM
;	  NONE FOUND
;	FOUND ONE	;F, U SET UP. J HAS JOB # IF ANY,
;			;T2 HAS TYPEIN T2

TTYCOM::MOVE	T1,BITTBL##+<FRCLIN##-<FRCLIN##/↑D32>*↑D32>
	TDNN	T1,CMDMAP##+<FRCLIN##/↑D32>
	SKIPA	T1,LINSAV##
	MOVEI	T1,FRCLIN##	;DO SYSTEM COMMANDS FIRST
	MOVEM	T1,LINSAV##
	CAIL	T1,TTPLEN##	;GREATER THAN HIGHEST LINE #?
TTYCM0:	SETZB	T1,LINSAV##	;YES, START AT LINE 0
	LSH	T1,-5		;SHIFT TO RIGHT PLACE
	HRLI	T1,TTCMPT##(T1)	;FORM AN AOBJN POINTER
TTYCM1:	SKIPE	T2,CMDMAP##(T1)	;GET A WORD OF BITS
TTYCM2:	JFFO	T2,TTYCM3	;FIND FIRST ONE BIT
	AOBJN	T1,TTYCM1	;LOOP TO TOP OF TABLE
	SKIPE	LINSAV##	;LOOKED AT THE ENTIRE TABLE?
	JRST	TTYCM0		;NO, START AT THE BEGINNING
	POPJ	P,0		;GIVE FAIL RETURN
TTYCM3:	MOVEI	T4,(T1)		;COPY WORD #
	LSH	T4,5		;SHIFT TO RIGHT PLACE
	ADDI	T4,(T3)		;ADD IN BIT NUMBER
	CAML	T4,LINSAV##	;SKIP IF LINE IS TOO SMALL
	JRST	TTYCM4		;ELSE FIX # AND PROCESS
	TDZ	T2,BITTBL##(T3)	;CLEAR BIT
	JRST	TTYCM2		;AND TRY NEXT
TTYCM4:	MOVEM	T4,LINSAV##	;SAVE THIS LINE #
	AOS	(P)		;GIVE SKIP RETURN
TTCM4A:	HRRZ	U,LINTAB##(T4)	;PICK UP LDB POINTER
TRESCN::HRRZ	F,LDBDDB(U)	;GET DDB ADDRESS IF ANY
	JUMPE	F,TRESC1	;JUMP IF NO DDB
	MOVE	T3,DEVMOD(F)
	TLNN	T3,TTYATC
TRESC1:	TDZA	J,J
	LDB	J,PJOBN##
IFN FTNET,<			;NETWORK AUTO-DISCONNECT FEATURE
	SETZ	T2,		;GET A ZERO FOR THE TIMER
	MOVE	T3,LDBDCH(U)	;GET THE DEVICE CHARACTERISTICS
	TRNE	T3,LDRREM	;IS A REMOTE TTY?
	DPB	T2,LDPADT	;  IF IT IS, THEN CLEAR HIS TIMER
>
	MOVE	T3,LDBDDB(U)	;KILL OR COMMAND?
	TLNN	T3,LDBCMF!LDBDET;FORCED COMMAND OR CLEANUP REQUIRED?
	TLNN	T3,LDBCMK	;NO, FORCED KJOB?
	JRST	TTYCM7		;NO.
	JRST	TTYCM5		;FORCED KJOB!
;DO FORCED COMMANDS OR CLEANUP 1ST, THEN FORCED KJOBS, THEN TYPED-IN COMMANDS ;⊗ TTYCM7 TTYCM5 TTYCM6

TTYCM7:	HRRM	U,.CPCML##	;MUST BE SAVED WHEN TTCMCA IS USED
	SCNOFF
	MOVE	T1,LDBTIT(U)	;GET TYPEIN CHAR ADR
	PUSHJ	P,CTISBP	; AND DEFINE IT AS THE INPUT BYTE POINTER
	SCNON
	HRRI	T3," "		;PRIME THE TYI ROUTINE
	TLNE	T3,LDBCMF	;FORCED COMMAND?
	MOVEI	T3,12		;YES. PREVENT EXTRA ARGUMENTS
	PUSHJ	P,CTISLC	;SAY IT IS LAST CHAR READ
	PUSHJ	P,FNDPDB##	;ADDRESS OF PDB
	  JFCL
	POPJ	P,0

TTYCM5:	MOVEI	T1,TTFCXC	;FORCE HALT 1ST SINCE IF TTKJOB IS CALLED DURING A COMMAND
	SKIPGE	JBTSTS##(J)	;MUST BE A JOB.  IS IT RUNNING
	JRST	TTYCM6		;NO.  JUST KILL IT
	MOVSI	T1,LDBCMK	;CLEAR KILL
	ANDCAM	T1,LDBDDB(U)	;FLAG
	MOVEI	T1,TTFCXK
TTYCM6:	PUSHJ	P,TTFORC	;FORCE COMMAND

;DON'T CALL CMDCLR, OR DELAYED COMMAND WILL NEVER BE SEEN AGAIN

	MOVE	T4,LINSAV##	;FIND LINE
	JRST	TTCM4A		;AGAIN
TTKJOB::PUSHJ	P,CNCMOD	;CONSOLE TO COMMAND LEVEL ;⊗ TTKJOB TTHALT
	MOVSI	T1,LDBCMK	;SET KILL REQUEST
	IORM	T1,LDBDDB(U)	;IN LDB
	HRRZ	F,LDBDDB(U)
	SKIPE	J,F
	LDB	J,PJOBN##
	AOS	COMCNT##	;MAKE COMCON SEE IT
	SKIPL	JBTSTS##(J)	;SKIP IF JOB IS IN RUN STATE
				; THIS DEPENDS UPON:
				; 1. RUN BIT BEING SIGN OF JBTSTS
				; 2. J=0 IF NO JOB
				; 3. JBTSTS+0 = 0
	PJRST	CMDSET


;TTHALT  --  HALT THE JOB ATTACHED TO THE TERMINAL
;
;THIS ROUTINE DOES NOT SET TERMINAL TO COMMAND LEVEL BECAUSE JACCT
;PROGRAMS MAY STILL NEED TO TYPEOUT AND THAT WOULD BLOCK THEM IN TO STATE.

TTHALT:	MOVEI	T1,TTFCXC	;HALT COMMAND INDEX
	PJRST	TTFORC		;FORCE THE ↑C
;ROUTINES TO ATTACH TERMINAL TO A JOB ;⊗ TTYATT TTYAT1

;1) CALL WHEN COMMAND DECODER DECIDES TO CREATE A JOB DUE TO
;A COMMAND BEING TYPED IN. THE LDB WILL ALREADY HAVE BEEN
;SET UP, BUT IT IS NOT YET LINKED TO A DDB
;
;CALL:	MOVE LINE,ADDRESS OF LDB
;	MOVE J,NEW JOB NUMBER
;	PUSHJ P,TTYATI
;	  ERROR RETURN	;ALREADY SOMEONE THERE (DDB POINTS AT HIM), OR
;			;NO MORE FREE DDB'S (DDB CONTAINS 0)
;	OK RETURN	;DDB, DDBLDB, AND LDBDDB SET UP
;
;2) CALL FROM COMMAND DECODER ON AN ATTACH COMMAND.
;
;CALL:	MOVE LINE,ADDRESS OF LDB
;	MOVE J,JOB TO ATTACH TO
;	PUSHJ P,TTYATT
;	  ERROR RETURN	;SOMEONE ALREADY ATTACHED (DDB POINTS TO HIM) OR
;			;NO SUCH DDB (DDB=0)
;	OK RETURN	;DDB, LDBDDB, NEW DDBLDB SET UP. OLD DDBLDB CLEARED

IFN FTATTACH,<

TTYATT::PUSH	P,U
	PUSHJ	P,TTYISA	;SEE IF DDB FOR TARGET JOB CAN BE ATTACHED
	  JRST	LPOPJ##		;NO, CAN'T DO IT
IFE FTPI,<JUMPE T1,TTYAT2>	;JUMP IF NO JOB IS ATTACHED TO LINE
IFN FTPI,<JUMPE T1,TTYAT1>	;JUMP IF DETACHED BUT SIGNAL DETACHING
	MOVEM	T1,(P)		;SAVE LDB OF TARGET JOB
	LDB	T1,LDPLNO	;OPERATOR DOING PREEMPTIVE ATTACH
				; GET OPERATOR'S LINE NUMBER
	EXCH	U,0(P)		;GET LDB OF OBJECT JOB
	LDB	T3,LDPLNO	;GET ITS LINE NUMBER TOO
	CAIE	T3,0(T1)	;ARE THEY THE SAME? (OPR ATTACHING
				; TO HIMSELF?)
	PUSHJ	P,PTYDET	;NO. DETACH OBJECT JOB, NOW IN LINE.
				; MUST RESPECT F
				;F NOW POINTS TO JOB BEING
				;PICKED UP BY TERMINAL IN 0(P)
	JRST	TTYAT2		;GO DO THE ATTACH
IFN FTPI,<
TTYAT1:	PUSHJ	P,SIGDET	;SIGNAL DETACHING
	JRST	TTYAT2		;GO DO THE ATTACH
>
> ;END IFN FTATTACH
TTYATI:: ;⊗ TTYATI TTYAT2 TTYAT3
IFN FTMP,<
	PUSHJ	P,INTLVL##	;IF AT UUO LEVEL
	  PUSHJ	P,ONCPU0##	;AVOID RACES WITH COMCON
>
	PUSH	P,U		;SAVE LINE DATA BLOCK ADDRESS
	PUSHJ	P,TTYSRC	;SEE IF THERE'S ALREADY A DDB. SHOULDNT BE.
	  PUSHJ P,DDBSRC	;OK. GET A NEW DDB.
	    JRST LPOPJ##	;ERROR. EITHER TTYSRC WON OR DDBSRC LOST
TTYAT2:	MOVE	U,0(P)		;GET LDB ADDR FROM STACK
	PUSH	P,F		;AND SAVE NEW DDB ADDRESS
	HRRZ	F,LDBDDB(U)	;GET OLD DDB IF ANY
	SKIPE	F		;ANY THERE?
	PUSHJ	P,TTYDT1	;YES. DETACH FROM IT BUT DON'T SET MONITOR CODE
	SKIPN	U		;SKIP IF LDB WAS FOUND
	PUSHJ	P,TTYKLQ	;NO, KILL OFF DDB
	MOVE	F,0(P)		;RESTORE NEW DDB ADDRESS
IFN FTMODM,<
	MOVE	U,-1(P)		;GET LDB ADDRESS, FOR DS POINTER
	MOVSI	T1,LDBCMF
	TDNE	T1,LDBDDB(U)
	JRST	TTYAT3
	MOVE	T1,LDBDCH(U)	;LOOK AT DATA SET BIT
	TRNN	T1,LDRREM	;IF NETWORK OR
	TRNN	T1,LDRDSD	;IF NOT A DATA SET
	JRST	TTYAT3		;NO DSCTAB ENTRY
	LDB	U,LDPDSC	;GET DATASET TABLE INDEX
	MOVEI	T1,0		;CLEAR TIME FIELD OF DATASET ENTRY
	DPB	T1,DSTMPL	; ..
>
TTYAT3:	MOVE	U,-1(P)		;ATTACH LDB FROM STACK TO DDB
	MOVE	T1,[XWD TTYATC,ASSCON]	;SET ATTACHED AND ASSIGNED BITS
	IORM	T1,DEVMOD(F)	;IN THE DEV DATA BLOCK
	HRRM	F,LDBDDB(U)	;SET LINK FROM DDB TO LDB
	HRRM	U,DDBLDB(F)	;AND LINK FROM LDB TO DDB
	PUSHJ	P,SETDVL##	;AND JOB NUMBER IN DDB
	HRRZM	F,TTYTAB##(J)	;STORE CONTROLLING DDB BY JOB NUMBER
	PUSHJ	P,SCNNAM	;SET UP PHYSICAL LINE NAME AND PUNIT
IFN FTNET,<PUSHJ P,SETSTA>	;SET CORRECT STATION NUMBER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ TTYAT4 TTYAT5 TTYAT6

;THIS CODE MAKES SURE BATCH BIT STAYS CORRECT

IFN FTATTA&FTTLIM,<
	PUSHJ	P,CTLJBU##	;GET PTY DDB IF ANY
	JUMPL	T1,TTYAT5
	MOVSI	T1,DVDIBP	;GET BATCH PTY BIT
	MOVE	T2,JBTLIM##(J)	;GET JBTLIM
	TDNN	T1,DEVCHR(F)	;IS IT A BATCH PTY?
	JRST	TTYAT4		;NO
	TLON	T2,(JB.LBT)	;YES, MAKE IT A BATCH JOB
	AOS	BATNUM##	;INCREMENT # OF BATCH JOBS
	MOVEM	T2,JBTLIM##(J)	;RESTORE JBTLIM
TTYAT4:
> ;END FTATTA&FTTLIM&FTPTYUUO

IFN FTPI,<PUSHJ	P,SIGDET>	;SIGNAL ATTACH (SAME AS DETACH)

TTYAT5:
IFN FTCIMP,<			;[arpa]
	MOVEI	T1,LDRIMP	;[arpa] IMP CONNECTION?
	TDNE	T1,LDBDCH(U)	;[arpa] ....
	  PUSHJ	P,IMPATT##	;[arpa] YES - LINK UP
>				;[arpa]
	POP	P,F
IFN	FTTLIM,<
	MOVSI	T1,(JB.LTL)	;GET DETACH TIME UNIT BIT
	TDNN	T1,JBTLIM##(J)	;SEE IF SET
	  JRST	TTYAT6		;NO -- LEAVE ALONE
	ANDCAM	T1,JBTLIM##(J)	;YES -- CLEAR IT
	MOVEI	T1,0		;NO TIME UNIT NOW
	DPB	T1,JBYLTM##	;CLEAR
TTYAT6:
> ;END IFN FTTLIM
	JRST	UPOPJ1##	;SKIP RETURN TO COMCON.
;SUBROUTINE TO LOOK FOR POSSIBLE LINE ALREADY ATTACHED TO TARGET JOB ;⊗ TTYISA TTYIS1
;ARGS	U=LINE ATTACH WAS TYPED OR
;	J=JOB NUMBER OF TARGET JOB
;VALUES	T1=ADDR OF LDB ATTACHED TO TARGET JOB OR 0 IF NONE
;NON-SKIP RETURN IF NO DDB FOR TARGET JOB OR DDB FOUND BUT MANY NOT ATTACH
;SKIP RETURN IF DDB FOUND AND MAY ATTACH TO IT

TTYISA::PUSHJ	P,SAVE2##	;SAVE P1 AND P2
	PUSH	P,U		;SAVE LINE BLOCK ADR OF GUY TYPING COMMAND
	PUSHJ	P,TTYSRC	;FIND THE DDB CONTROLLING THAT JOB
	  JRST LPOPJ##		;THERE ISN'T ANY. COMCON HAS GOOFED?
	SETZ	T1,
	JUMPE	U,LPOPJ1##	;IF NONE ATTACHED, GO ATTACH.
	EXCH	U,0(P)		;SOMEONE IS ATTACHED. ONLY THE OPERATOR
				;MAY USURP THE EXISTING CONNECTION
	PUSH	P,F		;SAVE NEW DDB
	HRRZ	F,LDBDDB(U)	;DDB OF OLD USER
	SKIPE	T1,F		;IF F=0, MAKE T1 0, SINCE PJOBN IS MEANINGLESS IF F=0
	LDB	T1,PJOBN##	;HIS JOB NUMBER
	LDB	P1,LDPLNO	;GET TERMINAL LINE # IN P1
	SUBI	P1,PTYOFS##	;SUBTRACT OFFSET OF PTY0
	JUMPL	P1,TTYIS1	;SEE IF A PTY
	CAIGE	P1,PTYN##	; ..
	SKIPA	F,PTYTAB##(P1)	;IT IS A PTY, GET DDB
TTYIS1:	TDZA	P1,P1		;NOT A PTY, USE JOB 0
	LDB	P1,PJOBN##	;GET JOB OWNING PTY
	POP	P,F		;RESTORE F
	MOVE	P2,FSFPPN##	;GET [1,2]
	CAME	P2,JBTPPN##(T1)	;IS JOB THAT TYPED COMMAND [1,2]?
	CAMN	P2,JBTPPN##(P1)	;OR COMMAND TYPED BY SON OF OPR?
	JRST	TPOPJ1##	;YES, ATTACH IS LEGAL

	HRRZ	T1,OPRLDB##
	CAIE	T1,0(U)		;IS THIS THE OPR?
	JRST	TPOPJ##		;NO. DISCARD OBJECT JOB'S LDB FROM
	JRST	TPOPJ1##	;STACK, AND GIVE ERROR RETURN TO COMCON
				;WITH DDB POINTING AT GUY ALREADY ATTACHED
;ROUTINE TO DETACH TERMINAL FROM A JOB. ;⊗ TTYDTC TTYDET PTYDTC PTYDET TTYKLQ
;CALL:	MOVE F,ADDRESS OF TTY DDB TO BE DETACHED
;	MOVE U,LDB  ADDRESS IF ENTRY AT PTYDTC
;	PUSHJ P,TTYDET
;	ALWAYS RETURN HERE

;CALLED FROM TTYATT AND COMCON (DETACH COMMAND)
;KILLS DDB IF NOT ATTACHED, ASSIGNED, OR INITED
;CLEARS LINKS TO DDB
;RESPECTS DDB


TTYDTC::TDZA	T2,T2		;FLAG TTYDTC ENTRY
TTYDET::MOVEI	T2,1		;SAME FOR TTYDET
IFN FTPI,<
	PUSH	P,T2		;SAVE T2
	PUSHJ	P,SIGDET
	POP	P,T2		;RESTORE IT
>
	HRRZ	U,DDBLDB(F)	;GET LDB ADDRESS
	LDB	T1,LDPLNO	;GET LINE NUMBER
	CAIN	T1,FRCLIN##	;RUNNING ON FRCLIN?
	JRST	@[EXP PTYDTC,PTYDET](T2)  ;YES, SKIP LOGGED OUT CHECK
	LDB	T1,PJOBN##	;GET JOB NUMBER
	MOVE	T1,JBTSTS##(T1)	;IS HE LOGGED IN?
	TLNE	T1,JLOG		; ..
	JRST	@[EXP PTYDTC,PTYDET](T2) ;YES, DISPATCH TO PTYDET
	LDB	T2,PJOBN##	;GET JOB NUM
	MOVE	T1,[SIXBIT/LOGOUT/]	;DON'T CLEAR
	CAMN	T1,JBTNAM##(T2)	;FOR LOGOUT SINCE USER COULD
	JRST	TTKJOB		;THEN GET OUT OVER QUOTA
	MOVSI	T1,JACCT	;CLEAR JACCT
	ANDCAM	T1,JBTSTS##(T2)	;IN STATUS
	JRST	TTKJOB		;GO KILL HIM
PTYDTC::LDB	T1,PJOBN##	;GET JOB NUMBER FROM DDB
	MOVSI	T2,CMWB		;AND COMMAND WAIT BIT
IFN FTMP,<CAME T1,COMJOB##>	;CURRENT JOB IN COMCON?
	TDNE	T2,JBTSTS##(T1)	;OR JOB IN COMMAND WAIT?
	JRST	[MOVSI	T1,LDBDET ;TELL COMRET TO CLEAN UP
		 IORM	T1,LDBDDB(U) ;JOB/COMMAND AT COMMAND EXIT
		 PJRST	DETCHK]	;WAIT FOR DETACH AND RETURN
PTYDET::PUSHJ	P,TTYDT1	;DISCONNECT DDB FROM LDB
	JUMPE	U,TTYKLQ	;IF NO LDB KILL OFF DDB
	PUSHJ	P,CNCMOD	;MAKE SURE LDB AT TOP LEVEL

;ROUTINE TO KILL DDB IF IT IS AN IDLE TTY DDB


TTYKLQ::PUSH	P,T1		;RESPECT T1
	MOVE	T1,DEVMOD(F)	;GET DEVICE MODE AND USE BITS
	TLNE	T1,DVTTY	;IS IT A TTY DDB?
	TDNE	T1,[XWD TTYATC,ASSCON+ASSPRG]	;YES, ANY REASON TO KEEP DDB?
	JRST	TPOPJ##		;YES.
	PUSHJ	P,TTYKIL	;NO. GO KILL THE DDB
	JRST	TPOPJ##		;AND RESTORE T1 ON RETURN
;SUBROUTINE TO DISCONNECT A TERMINAL FROM A JOB WITHOUT SETTING TERMINAL TO MONITOR LEVEL ;⊗ TTYDT1 TTYDTX SIGDET DETCHK DETCH1
;THIS IS SO ATTACH UUO WILL LEAVE TERMINAL AT ITS ORIGINAL LEVEL (MONITOR OR USER MODE)

TTYDT1:	HRRZ	U,DDBLDB(F)	;GET LINKED LINE ADDRESS
	HLLZS	DDBLDB(F)	;DISCONNECT LDB FROM DDB
	JUMPE	U,TTYDTX	;IF NO LDB, KILL OFF DDB
	HLLZS	LDBDDB(U)	;DISCONNECT DDB FROM LDB
	HRRZS	DEVNAM(F)	;CLEAR LH OF DEVNAM TO NOT CONFUSE DEVCHR, ETC.
				;KEEP RH FOR SYSTAT, ETC.
IFN FTDAEM!FTTLIM,<
	LDB	T1,PJOBN##	;SEE IF THIS JOB WAITING FOR DAEMON
>
IFN FTTLIM,<
	MOVSI	T2,(JB.LBT)	;BATCH BIT
	TDNE	T2,JBTLIM##(T1)	;IF WAS BATCH JOB
	SOS	BATNUM##	;DECR. BATCH JOB COUNT
	ANDCAM	T2,JBTLIM##(T1)	;CLEAR BIT SO OPERATOR CAN DETACH
>
IFN FTDAEM,<
	MOVE	T1,JBTSTS##(T1)	;GET JOB STATUS WORD
	TRNN	T1,JDC		;DCORE COMMAND WAITING?
>
	PUSHJ	P,TYIEAT	;NO. CLEAR ANY PENDING COMMAND
	MOVE	T1,LDBDCH(U)	;GET LINE CHARACTERISTICS
	TRNE	T1,LDRPTY	;A PTY LINE?
	PUSHJ	P,PTMNMD##	;YES. WAKE CONTROLLER
TTYDTX:	POPJ	P,

IFN FTPI,<
SIGDET:	SIGNAL	C$DATT
	  POPJ	P,
	POPJ	P,
>

;ROUTINE TO MAKE SURE A LINE IS DETACHED BEFORE PROCEDING
;CALL WITH U POINTING AT THE LDB IN QUESTION
DETCHK:	PUSH	P,J		;SAVE J
	MOVE	J,.CPJOB##	;SET TO CURRENT JOB
DETCH1:	MOVSI	T1,LDBDET	;WAITING FOR COMMAND
	TDZN	T1,LDBDDB(U)	; TO COMPLETE?
	JRST	JPOPJ##		;NO
	PUSHJ	P,SLEEPF##	;YES, WAIT UNTIL ITS DONE
	JRST	DETCH1		;TRY AGAIN
;ROUTINE TO RELEASE A TTY DDB. CALL WITH DDB SET UP. ;⊗ TTYREL TTYRL0 TTYRL1 TTYRL2


TTYREL::MOVE	T1,[XWD IOW,IOACT]	;CLEAR OUT S
	ANDM	T1,DEVIOS(F)	; IN CORE
	SKIPE	DINITF##	;IN SYSINI?
	JRST	TTYRL2		;YES--SKIP THIS
	PUSHJ	P,SAVE1##	;SAVE CHANNEL NUMBER
	MOVEI	P1,0		;START AT CHANNEL ZERO
TTYRL0:	PUSHJ	P,NXTCH##	;NEXT CHANNEL
	  JRST	TTYRL1		;ALL CHANNELS HAVE BEEN LOOKED AT
	SOS	P1		;ADJUST P1
	CAIN	P1,@-1(P)	;CHANNEL BEING RELEASED
	AOJA	P1,TTYRL0	;YES
	CAIE	T1,(F)		;NO SAME DDB OPEN ON ANOTHER CHANNEL?
	AOJA	P1,TTYRL0	;NO
	JRST	TTYRS1		;YES, DON'T MAKE THE DDB GO AWAY
TTYRL1:
IFN FT2741&FTCAFE <
	HRRZ	U,DDBLDB(F)	;GET LINE BLOCK ADR
	JUMPE	U,TTYRL2	;BYPASS IF NONE
	MOVSI	T1,LILAPL	;BIT FOR APL MODE
	ANDCAM	T1,LDBISR(U)	;CLEAR APL MODE
>;END OF IFN FT2741
TTYRL2:	MOVE	T1,[XWD TTYATC,ASSCON]	;IS TTY ATTACHED OR ASSIGNED?
	TDNE	T1,DEVMOD(F)	; ..
	JRST	TTYRS1		;YES. KEEP DDB AROUND. RETURN.
;	JRST	TTYKIL		;NO. GO DISCARD DDB.
;ROUTINE TO CLEAR A TTY DDB AND MAKE IT AVAILABLE TO THE POOL ;⊗ TTYKIL TTYKL1
;CALL:	MOVE F,ADDRESS OF DEVICE DATA BLOCK KNOWN TO BE THROUGH USE.
;	PUSHJ P,TTYKIL
;	ALWAYS RETURN HERE
;RESPECTS F & S, CLOBBERS T1


TTYKIL::SETZM	DEVLOG(F)	;CLEAR LOGICAL NAME
	MOVSI	T1,IOFST	;INITIAL STATE OF S WORD
	MOVEM	T1,DEVIOS(F)	;PLACE IN CORE STATUS WORD
IFN FTPI,<
	SKIPE	DEVPSI(F)	;USER INTERRUPTING ON THIS
	PUSHJ	P,PSIRMV##	;YES, REMOVE PSI LINKS
>
	PUSHJ	P,CLRDVL##	;NO JOB OWNS IT ANY MORE.
IFN FTLINK,<			;[link]
	PUSHJ	P,LNKBRK##	;[link] CUT OFF LINKS
>				;[link]
	PUSH	P,U
	HRRZ	U,DDBLDB(F)	;GET LINK TO LINE DATA BLOCK
	JUMPE	U,TTYKL1	;BYPASS IF NO LINK.
	PUSHJ	P,TTYSTC	;PUT LINE AT COMMAND LEVEL
	PUSHJ	P,TTYCPT	;CLEAR PAPER TAPE BITS
	MOVSI	T1,LPLCLR	;CLEAR PAGE BITS
	ANDCAM	T1,LDBPAG(U)	;SO XON AND XOFF ARE ECHOED PROPERLY
	MOVSI	T1,LDLSSO!LDLBKA	;CLEAR THE STOP OUTPUT BIT	
	ANDCAM	T1,LDBDCH(U)	;IN THE DCH WORD
IFN FTCIMP,<			;[arpa]
	SETZM	LDBIMP(U)	;[arpa] CLEAN UP IMP PARTS OF LDB
	SETZM	LDBQUO(U)	;[arpa] ....
>				;[arpa]
	PUSHJ	P,CLRIM1	;MAKE SURE NOT IN IMAGE MODE
	PUSH	P,S		;IN CASE SOME CALLER SOMEWHERE CARES
	MOVEI	S,0		;CLEAR ALL THOSE BITS IN LDBDCH
	PUSHJ	P,UUOLDB	;CLEAR OUT LDB
	POP	P,S		;THIS IS REALLY SUPERCAUTION
TTYKL1:	MOVSI	T1,DEPRAS	;TEST FOR DDB RESTRICTED
	TDNE	T1,DEVSTA(F)	;IS IT A RESTRICTED TTY?
	JRST	[POP P,U
		 JRST TTYRS1]	;YES, SO KEEP DDB
	SETZM	DEVNAM(F)	;CLEAR PHYSICAL NAME
	HLLZS	LDBDDB(U)	;REMOVE LINK TO DEAD DDB
	HLLZS	DDBLDB(F)	;REMOVE LINK FROM DDB TO LINE DATA BLOCK
	MOVE	T1,[XWD TTYUSE+TTYATC,ASSCON+ASSPRG]
	ANDCAB	T1,DEVMOD(F)	;LAST CLEAR THESE, MAKING DDB AVAILABLE
	JRST	UPOPJ##		;AND RETURN TO CALLER.
;SUBROUTINE CALLED ON RESET FROM UUOCON ;⊗ TTYRES TTYRSA TTYRSC TTYRSB TTYRS1 TTYRS2


TTYRES::PUSHJ	P,SAVE1##
	MOVEI	P1,JS.NTO
	TDNE	P1,JBTSTS##(J)
	XORB	P1,JBTSTS##(J)
	ANDI	P1,JS.NTO
	MOVEI	F,SCNDDB
TTYRSA:	LDB	T1,PJOBN##
	CAIE	T1,(J)
	JRST	TTYRSB
	JUMPN	P1,TTYRSC
	SETZB	T1,DEVSTS(F)
	DPB	T1,BYTCNT
TTYRSC:	MOVE	T1,[TTYATC,,ASSCON]
	TDNN	T1,DEVMOD(F)
	PUSHJ	P,TTYKIL
TTYRSB:	HLRZ	F,DEVSER(F)
	MOVE	T1,DEVMOD(F)
	TLNE	T1,DVTTY
	JRST	TTYRSA
	HRRZ	F,TTYTAB##(J)	;GET CONTROLLING DDB ADDRESS
	JUMPE	F,CPOPJ##	;REALLY HAS TO BE ONE
TTYRS1:	MOVE	S,[IOLBKA,,IOSBKA!IOSTEC!IOSFCS+D] ;GET BITS

;THE FOLLOWING CHECK FOR NOT LOGGED IN, RUNNING "LOGIN"
; IS TO AVOID BREAKING ANCIENT "FEATURE" OF NOECHO GETTING
; SET BY LOGIN COMMAND.

	HRRZ	U,DDBLDB(F)	;LINK TO LDB
	JUMPE	U,TTYRS2	;NOT BATCH IS DETACHED
	PUSHJ	P,PTBTCH##
	  JRST	TTYRS2
	MOVE	T1,JBTSTS##(J)	;GET THIS STATUS
	MOVE	T2,JBTPRG##(J)	; AND PROGRAM NAME
	TLNN	T1,JLOG		;IS HE NOT LOGGED IN?
	CAME	T2,[SIXBIT/LOGIN/] ; AND RUNNING LOGIN
TTYRS2:	IORI	S,IOSNEC	;NOT BOTH, WE CAN CLEAR NOECHO
	ANDCAB	S,DEVIOS(F)	;CLEAR THESE BITS ON RESET
	JUMPE	U,CPOPJ##	;SKIP IT IF DETACHED
	MOVEI	T1,0		;CLEAR THE AUTO
	DPB	T1,LDPACR	;CRLF COUNTER
	PUSHJ	P,CLRIM1	;CLEAR IMAGE MODE
	MOVSI	T1,LDLBKA	;THE BREAK-ON-ALL-CHARACTERS BIT
	ANDCAM	T1,LDBDCH(U)	;CLEAR IN LDB SINCE TTYUSR ALREADY CALLED
				; AND WILL HAVE SET IT IF IOLBKA WAS SET
	PUSHJ	P,UUOLDB	;AND MAKE LDB AGREE
	PJRST	SETCHP		;FORCE CHANGE OF CHARACTERISTICS
;SUBROUTINE TO RETURN ONE CHARACTER FROM THE INPUT BUFFER. CHARACTER ;⊗ COMTYI COMTI1 COMTIX USEARO COMTYO
;RETURNED IN T3.

COMTYI::PUSH	P,T2		;SAVE AC FOR OUTSIDE WORLD
	PUSHJ	P,CTIGLC	;GET THE LAST CHARACTER
	SKIPN	T3		;IS ANYTHING THERE FROM BEFORE?
	MOVEI	T3,12		;NO. ASSUME END OF LINE
	PUSHJ	P,SPCHEK	;YES. WAS IT A BREAK?
	  JFCL
	TLNN	T1,CHBRK	; ..
COMTI1:	PUSHJ	P,CTIGNC	;NO. GET ANOTHER CHARACTER (CCTYI OR ONCE)
	ANDI	T3,177		;COMCON DOESN'T WANT PARITY
	PUSHJ	P,SPCHEK	;CONVERT TO CONSISTENT BREAKS
	  JFCL			;ORDINARY CHARACTER
	TLNE	T1,CHCRET	;CARRIAGE RETURN?
	JRST	COMTI1		;YES. GO GET LINEFEED INSTEAD
	TLNE	T1,CHBRK	;BREAK?
	MOVEI	T3,12		;YES--MAKE INTO LINE FEED
	TLNE	T1,CHCNC	;IS THIS A CONTROL-C?
	MOVEI	T3,3		;YES--CONTROL-C IS STRONGER THAN LF
	PUSHJ	P,CTISLC	;SAY THAT THIS IS THE "LAST CHAR"
COMTIX:	PJRST	T2POPJ##	;RESTORE AC T2 AND RETURN


;SUBROUTINE TO SEND 1 CHAR, SENDING CONTROL CHARS AS ↑X
;OTHERWISE, SAME AS COMTYO

USEARO::PUSHJ	P,SPCHEK	;SPECIAL CHAR?
	  JRST	COMTYO		;NO, FORGET IT
	TLNN	T1,CHUAE	;ECHO AS ↑X?
	  JRST	COMTYO		;NO, GO ECHO NORMALLY
	PUSH	P,T3		;SAVE THE CHAR
	MOVEI	T3,336		;GET AN ARROW
	PUSHJ	P,COMTYO	;SEND IT
	POP	P,T3		;RESTORE CHAR
	TRC	T3,300		;CONVERT TO LETTER
;;	JRST	COMTYO		;AND GO TYPE IT


;SUBROUTINE TO SEND 1 CHARACTER, CHARACTER IN T3.
;PRESERVES T2 & T3

COMTYO::PUSH	P,T2		;SAVE AC
	PUSH	P,T3
	ANDI	T3,177		;SAVE PUSHJ TO PEVEN8, DO IT HERE
	MOVSI	T2,CHEPAR	;GET PARITY BIT
	TDNN	T2,CHTABL(T3)	;IS CHARACTER ALREADY EVEN PARITY?
	TRO	T3,200		;NO, MAKE IT SO
	PUSHJ	P,@.CPTOA##	;CALL  CCTYO, CTYWAT, OR ONCE ROUTINE
	POP	P,T3		;RESTORE
	JRST	T2POPJ##	; AC'S AND RETURN
;ROUTINE TO SWITCH TERMINAL TO USER PROGRAM LEVEL AND START USER RUNNING ;⊗ TTYUSW TTYUSR TTYUS1 TTYSTC TTYSTR

TTYUSW::TDZA	S,S		;DON'T CLEAR WAIT BITS
TTYUSR::MOVE	S,[XWD IOW,IOACT]	;CLEAR WAIT BITS
	HRRZ	F,LDBDDB(U)	;GET ATTACHED DDB IF ANY
	JUMPE	F,TTYUS1	;JUMP IF NOT ATTACHED
	ANDCAB	S,DEVIOS(F)	; ..
	MOVSI	T1,LDLBKA	;THE VOLATILE BREAK-ON-ALL BIT
	TLNE	S,IOLBKA	;NEED TO RE-SET IT IN LDB?
	IORM	T1,LDBDCH(U)	;YES
	MOVSI	S,IOLBKA	;NOW CLEAR OUT
	ANDCAB	S,DEVIOS(F)	; ANNOYING TEMP BIT
	PUSHJ	P,UUOLDB	;MAKE LINE AND DEVIOS AGREE
TTYUS1:	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNE	T1,LDRPTY	;IS THIS A PTY?
	PUSHJ	P,PTMNMZ##	;YES. TELL CONTROLLER
	MOVSI	T1,LDLCOM	;PUT TERMINAL IN USER MODE
	ANDCAM	T1,LDBDCH(U)	;MAY BE DETACHED, BUT WILL WAIT
				; AT UUO LEVEL IF NEEDED
	PJRST	SETRUN##	;SET USER'S RUN BIT AND RETURN



TTYSTC::HLL	U,LDBDCH(U)	;SEE IF THIS LINE IS SLAVED
	MOVSI	T1,LDLCOM	;PREPARE TO SET BIT
	TLNN	U,LDLSLV	;SLAVED?
IFN FTMIC,<			;IF MIC
	IORM	T1,LDBDCH(U)	;NO. SET COMMAND BIT
	PUSHJ	P,MICWAK	;WAKE MIC IF NECESSARY
> ;END OF IF MIC
IFE FTMIC,<IORB T1,LDBDCH(U)>	;NO, SET COMMAND BIT
	TRNE	T1,LDRPTY	;PTY-DRIVEN LINE?
	PUSHJ	P,PTMNMD##	;YES. TELL CONTROLLER
TTYSTR::MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNE	T1,LDRPTY	;IS IT A PTY?
	PUSHJ	P,PTYPE##	;YES. WAKE THE PTY CONTROLLER
	PUSHJ	P,COMQ		;AT COMMAND LEVEL?
	  PJRST NOCTRO		;NO. JUST CLEAR ↑O BIT
	PUSHJ	P,TYIEAT	;YES. CLEAR THE COMMAND IN CASE MORE
	PUSHJ	P,STRTDL	;ECHO ONE DEFERRED LINE IF NECESSARY
	SKIPLE	LDBBKC(U)	;ANY MORE COMMANDS?
	PUSHJ	P,COMSET	;MAYBE. SET BIT IF AT COM LEVEL
	PJRST	NOCTRO		;CLEAR OSU AND RETURN
;HERE AT COMPLETION OF A COMMAND ;⊗ TTYCMR TTCMR1

TTYCMR::PUSH	P,T1		;SAVE PREVIOUS LDPCMX
	TRNN	F,-1		;ANY JOB?
	PUSHJ	P,TTYCPT	;NO. CLEAR PAPER-TAPE BITS
	AOS	T1,LINSAV##
	CAIL	T1,TTPLEN##
	SETZM	LINSAV##
	HLL	T2,LDBDDB(U)	;GET COMMAND REQUEST BITS
	POP	P,T1		;COMMAND JUST FINISHED
	LDB	T3,LDPCMX	;CURRENT
	CAME	T1,T3		;CHANGED?
	TLNN	T2,LDBCMF	;FORCED
	SKIPA			;NO CHANGE OR NOT FORCED
	POPJ	P,		;NEW FORCED-DO IT
	MOVEI	T1,L2RECS	;SET EAT-COMMAND-SYNC BIT
	TLNN	T2,LDBCMF	;(UNLESS FORCED COMMAND)
	IORM	T1,LDBBY2(U)	;IN LINE DATA BLOCK
	MOVSI	T1,LDBCMR+LDBCMF;CLEAR COMMAND REQUEST BITS
	ANDCAB	T1,LDBDDB(U)	;IN BASE WORD OF LDB
	MOVE	T1,LDBDCH(U)	;GET THE LINE'S CHARACTERISTIC
	TLNN	T1,LDLBKA+LDLIMI;ARE WE BREAKING ON ALL CHARACTERS
				; OR IN IMAGE MODE?
	JRST	TTCMR1		;NO, CONTINUE ON
	SKIPLE	LDBTIC(U)	;YES, DO WE HAVE ANY CHARACTERS
				; IN THE INPUT BUFFER?
	PUSHJ	P,RCVWAK	;YES, WAKE THE JOB
				;NO,...
TTCMR1::MOVE	T1,LDBDDB(U)	;GET THE LINES LDBDDB & CONTINUE
	TLNN	T1,LDBCMK	;FORCED KJOB PENDING?
IFN FTMIC,<			;IF MIC
	PUSHJ	P,CMDCLR	;NO, CLEAR COMMAND BIT
	PJRST	MICWAK		;WAKE MIC UP IF NEC & RETURN TO COMCON
> ;END OF IF MIC
IFE FTMIC,<			;IF NOT MIC
	PJRST	CMDCLR		;NO, CLEAR COMMAND BIT
	POPJ	P,0		;YES, DO NOT CLEAR COMMAND BIT
> ;END OF IF NOT MIC
	SUBTTL	SUBROUTINES FOR COMCON OR UUO LEVEL ;⊗ TYO TYO7W TYO9W TYOX TYO9M TYO9A LnkCpy

;COMMON UUO LEVEL ROUTINES
;TYO7W IS USED TO TAKE A 7-BIT CHARACTER IN T3
; GO INTO I/O WAIT IF JOB DETACHED OR IF THE LINE'S
; OUTPUT BUFFER IS RATHER BIG, THEN PLACE THE CHARACTER IN OUTPUT
; STREAM, AND START OUTPUT IF NEEDED.
;TYO9W IS SAME, BUT ASSUMES PARITY AND NINTH BIT ARE AS DESIRED.
;TYO CHOOSES ONE OF THE ABOVE, DEPENDING ON MODE IN S
;CALL TYO9W WITH SIGN BIT OF T3 SET TO AVOID BLOCKING.  SIGN BIT CLEARED IF CHAR ACTUALLY OUTPUT
; (USED TO AVOID WTP STOPED ON CALL FROM TTMORE)
;CALL WITH DDB SET UP, CHARACTER IN T3.
;IF CALLED AT TYO, S MUST BE SET UP ALSO
TYO:	TRNN	S,I!PIMMOD	;IMAGE MODE USE OWN PARITY
TYO7W:	ANDI	T3,177
TYO9W:	MOVE	S,DEVIOS(F)
	TRNE	S,IODERR	;↑C TYPED ON TTYNNN
	JRST	[TLZ T3,(1B0)	;FLAG WE GOT CHAR
		 POPJ	P,]
	MOVSI	S,IO		;INDICATE OUTPUT
	IORB	S,DEVIOS(F)
	HRRZ	U,DDBLDB(F)	;GET LINE ADDR IF ANY
	JUMPN	U,TYOX		;ATTACHED, PROCEED
	JUMPL	T3,CPOPJ	;IF ASYNCHRONOUS RETURN
	PUSHJ	P,CKATOW	;WAIT FOR ATTACH
	SKIPA
TYOX:	PUSHJ	P,CKATO1
	MOVE	T1,TTFREN##	;MAKE SURE THERE'S SOME CHARACTER SPACE LEFT
	CAIGE	T1,3		;LEAVE 3 CHUNKS FOR SAFETY
	JRST	[JUMPGE T3,TYONFC ;NO,WAIT
		 POPJ	P,]
	MOVE	T1,LDBTOC(U)	;GET OUTPUT STREAM LENGTH
	CAML	T1,TIWRNN	;IS HE OVER QUOTA?
	JRST	[JUMPGE T3,TYOOBF ;WAIT IF ATTACHED
		 POPJ	P,]
IFN FTMIC,<
IFN FTMLOG,<
	SKIPN	LDBLOT(U)	;IS HE LOGGING
	JRST	TYO9M		;NO
	ADD	T1,LDBLOC(U)
	CAIL	T1,↑D100
	JRST	MICLGX		;GO WAKE UP MIC
TYO9M:>	;END OF FTMLOG CONDITIONAL
>;END IFN FTMIC
	TLZ	T3,(1B0)	;FLAG WE GOT THE CHARACTER
	MOVE	T1,LDBDCH(U)	;CHECK FOR OUTPUT SUPPRESS
	SKIPL	LDBOFL(U)
	TRNE	T1,LDROSU	; ..
	POPJ	P,0		;NO. JUST RETURN DUE TO ↑O
TYO9A:
IFN FTLINK,<			;[link]
	PUSHJ	P,CHKLNK##	;[link] SEND CHAR (COMCON/UUO LEVEL) TO ANY LINKS
LnkCpy::			;[link] entry to avoid LnkSer recursion.
>				;[link]
	SCNOFF			;NO RACES
	STCHK	T3,LDBTOP(U)	;STORE CHARACTER IN CHUNKS
	AOS	LDBTOC(U)	;COUNT UP OUTPUT STREAM LENGTH
	SCNON			;ALLOW INTERRUPTS
IFN FTMIC,<			;IF MIC
	PUSHJ	P,MICPOS	;YES SET UP AND CHECK POSITION
> ;END OF IF MIC
	PJRST	TOPOKE		;START OUTPUT FOR THE LINE
TYOVRG:	SCNOFF			;NO INTERRUPTS ;⊗ TYOVRG TYOVR1 TYONFC MICLGX TYOOBF
	SKIPE	T1,LDBTOT(U)	;IF ALREADY A GOOD POINTER
	JRST	TYOVR1		;DON'T WASTE A GOOD CHUNK
	PUSHJ	P,GETCKZ	;GET A CHUNK FROM FREELIST
	ADD	T1,[POINT 9,1]	;MAKE INTO A BYTE POINTER
	MOVEM	T1,LDBTOT(U)
TYOVR1:	MOVEM	T1,LDBTOP(U)	;PUT IN TYPEOUT STRING ADDRESSES
	SETZM	LDBTOC(U)	;MAKE SURE COUNT IS ZERO
	JRST	SONPPJ		;REENABLE INTERRUPTS AND RETURN


;HERE IF NO FREE CHUNKS
TYONFC:	PUSH	P,16		;ACS USED BY SETSLP
	PUSH	P,17
	PUSH	P,T3
	PUSH	P,U
	MOVEI	T1,5		;SLEEP FOR 5 SEC.
	PUSHJ	P,SLEEP##	; ..
	POP	P,U		;RESTORE AC(S
	HRRZ	F,LDBDDB(U)
	POP	P,T3
	POP	P,17
	POP	P,16
	JRST	TYO9W


IFN FTMIC&FTMLOG,<
MICLGX:	PUSHJ	P,MICWAK
	JUMPL	T3,TYO9M		;DON'T BLOCK IF FROM TTMORE
> ;END OF FTMLOG CONDITIONAL

;HERE IF OUTPUT BUFFER FULL
TYOOBF:	PUSHJ	P,TOWAT1
	JRST	TYO9W

;SUBROUTINE TO SETUP A BYTE COUNT AND POINTER TO A USER'S BUFFER ;⊗ SRLPTR
;CALLING SEQUENCE:
;	MOVE	S,DEVIOS(F)
;	HRRZ	P1,USER VIRTUAL ADDRESS OF BUFFER
;	PUSHJ	P,SRLPTR
;
;ON RETURN P1 IS A BYTE POINTER TO THE USER BUFFER AND P2 IS THE MAXIMUM
;BYTE COUNT FOR THE BUFFER.

SRLPTR:	ADD	P1,[POINT 7,2]	;ASSUME ASCII MODE (AND SKIP .BFCNT WORD)
	TRNE	S,PIMMOD	;PACKED IMAGE MODE?
	HRLI	P1,(POINT 8,)	;YES, USE 8-BIT BYTES
	TRNE	S,I		;REGULAR IMAGE MODE?
	HRLI	P1,(POINT 36,)	;YES, USE 36-BIT BYTES
	TRNN	S,I!PIMMOD	;ASCII MODE?
	IMULI	P2,5		;YES, 5 BYTES PER WORD
	TRNE	S,PIMMOD	;PACKED IMAGE MODE?
	IMULI	P2,4		;YES, 4 BYTES PER WORD
	POPJ	P,
;SUBROUTINE FOR COMMAND LEVEL OUTPUT ;⊗ CCTYO CCTYO9


CCTYO::	JUMPE	U,CPOPJ##	;U MUST BE SET UP
IFN FTCIMP,<			;[arpa]
	ANDI	T3,177		;[arpa] COMPUTE PARITY HERE SINCE IMPSER CALLS
CCTYO9::			;[arpa] THIS ROUTINE TO OUTPUT TELNET CODES
>				;[arpa]
	MOVE	T1,LDBTOC(U)	;GET COUNT
	SUBI	T1,↑D200
	SKIPLE	T2,TTFREN##	;SPACE IN STRINGS?
	CAML	T1,TIWRNN	;YES. SPACE IN THIS GUY'S AREA?
	POPJ	P,0		;NO. QUIT.
	CAIL	T2,3
	SKIPN	TTFTAK		;IS THERE A FREE LIST?
	POPJ	P,		;NO--PUNT
IFE FTCIMP,<			;[arpa]
	ANDI	T3,177		;FORCE EVEN PARITY SINCE CCTYO NEVER DOES IMAGE
>				;[arpa]
	JRST	TYO9A		;YES. GO TYPE IT.

	$LOW			;MUST BE IN THE LOW SEGMENT FOR ONCE-ONLY ;⊗ CTYTYP CTYTYL CTYPAR
;SUBROUTINE TO PRINT ON CTY IN EMERGENCY OR ONCE-ONLY
; WHEN INTERRUPT SYSTEM CANNOT BE USED OR TRUSTED
;CALL:	MOVEI	T1,ADR OF ASCIZ MESSAGE
;	PUSHJ	P,CTYTYP
;	ALWAYS	RETURN

CTYTYP::HRLI	T1,440700	;FORM BYTE POINTER
CTYTYL:	ILDB	T3,T1		;GET NEXT CHARACTER
	JUMPE	T3,LCPOPJ	;END OF MESSAGE?
				;(CPOPJ IS IN HISEG, SO DON'T USE IT)
	PUSHJ	P,CTYWAT	;NO, PRINT IT ON CTY AND WAIT
	JRST	CTYTYL		;GO GET NEXT CHAR.



;ROUTINE RESIDING IN LOSEG TO COMPUTE PARITY.
; USED ONLY FOR EMERGENCY CTY OUTPUT ROUTINES.
; USES T1

CTYPAR:	MOVEI	T1,(T3)
	LSH	T1,-4		;FOLD INTO LOW 4 BITS
	XORI	T1,(T3)
	TRCE	T1,14		;CHECK BITS 32 AND 33
	TRNN	T1,14
	TRC	T3,200		;IF EVEN PARITY COMPLEMENT RESULTS
	TRCE	T1,3
	TRNN	T1,3
	TRC	T3,200		;IF EVEN PARITY COMPLEMENT RESULTS
	POPJ	P,		;RETURN
;SUBROUTINE FOR ERROR MESSAGE TO CTY DURING PARITY ERROR STOP ;⊗ CTYWAT
;CALL:	MOVEI	T3,CHARACTER
;	PUSHJ	P,CTYWAT
;	RETURN AFTER CHARACTER HAS BEEN TYPED
;NOTE:  DOES NOT USE INTERRUPT SYSTEM SO MESSAGE WILL GET OUT BEFORE HALT
;THIS SUB CALLED BY COMTYO WHEN COMTOA PATCHED

CTYWAT::PUSH	P,T1
	PUSHJ	P,CTYPAR	;COMPUTE PARITY WITH LOSEG ROUTINE

IFN FTKI10,<
	CONSZ	CTY,20		;WAIT FOR CTY TO BE IDLE
	JRST	.-1		;NO, SO NOT GARBLE ON GOING OUTPUT
	DATAO	CTY,T3		;YES, SEND OUT CHAR
	PUSHJ	P,OPRFIL
	CONSZ	CTY,20		;WAIT FOR CTY TO BE IDLE
	JRST	.-1		;NO, OTHERWISE HALT OR RESET WILL CLOBBER LAST CHAR
	JRST	OPRFI2		;YES, OK TO RETURN
>;END FTKI10

IFN FTKS10,<
	SKIPE	CTYOWD		;CAN WE TYPE YET ?
	JRST	.-1		;WAIT A WHILE
	TRO	T3,CTYOVL	;VALID FLAG
	MOVEM	T3,CTYOWD	;PUT UP FOR FRONT END TO SEE IT
	RDAPR	T1		;GET PROCESSOR PIA
	ANDI	T1,SP.PIA	;LEAVE ONLY THE PIA
	WRAPR	SP.SSF+SP.IFE(T1) ;INTERRUPT THE FRONTEND
	SKIPE	CTYOWD		;WAIT FOR CTY TO BE IDLE
	JRST	.-1		;OTHERWISE HALT OR RESET WILL CLOBBER LAST CHAR
	JRST	OPRFI2		;OK TO RETURN
>;IFN FTKS10

IFN FTKL10,<
	PUSHJ	P,SPCTYO##	;SEND CHAR OVER
	PUSHJ	P,SPCWTO##	;WAIT FOR OUTPUT TO COMPLETE
	  JRST	.-1
	JRST	OPRFI2		;RESTORE T1
				;AND RETURN
>;END IFN FTKL10
	$HIGH			;BACK TO THE HIGH SEGMENT ;⊗ TTYCPT OPRFIL OPRFI1 OPRFI1 OPRFI1 OPRFI2 LCPOPJ
;SUBROUTINE TO CLEAR PAPER TAPE INPUT BITS, RETURNS LDBDCH IN T1
TTYCPT::MOVSI	T1,L2LTAP	;CLEAR TTY TAPE COMMAND BIT
	ANDCAM	T1,LDBBY2(U)	;IN BY2
	MOVEI	T1,L2RXON	;CLEAR XON IN EFFECT
	ANDCAB	T1,LDBBY2(U)	;AND RETURN NEW STATUS
	POPJ	P,		;RETURN

	$LOW			;MUST BE IN THE LOW SEG FOR EMERGENCIES

;SUBROUTINE TO ADD A DELAY FOR SLOW CTY'S
;CALL WITH:
;	MOVEI	T3,CHAR
;	PUSHJ	P,OPRFIL
;USED ONLY WITH PI SYSTEM OFF
OPRFIL::ANDI	T3,177		;ONLY CHAR BITS
	PUSH	P,T1		;SAVE T1
	MOVEI	T1,0		;ASSUME NO FILLERS
	CAIN	T3,12		;LF GETS
	MOVEI	T1,CTYDLF##	;8 TICKS
	CAIN	T3,15		;CR GETS
	MOVEI	T1,CTYDCR##	;18 TICKS
	JUMPE	T1,OPRFI2	;RETURN
	ADDM	T1,TIME##	;UPDATE TIME
IFN FTKI10,<
OPRFI1:	CONSO	APR,XP.CLK	;DID CLOCK TICK?
	JRST	OPRFI1		;NO -- WAIT FOR IT
	CONO	APR,XP.CCF	;CLEAR CLOCK FLAG
>;END IFN FTKI10

IFN FTKS10,<
OPRFI1:	RDAPR	T1		;GET CLOCK FLAG
	TRNN	T1,SP.ITI	;DID CLOCK TICK ?
	JRST	OPRFI1		;NOT YET
	WRAPR	SP.CSF+SP.ITI	;CLEAR CLOCK FLAG
>;IFN FTKS10

IFN FTKL10,<
OPRFI1:	CONSO	TIM,TI.ITD	;CLOCK "TICK" ?
	JRST	OPRFI1		;NOT YET
	CONO	TIM,@ONCKLT##	;YES, CLEAR AND SET FOR ANOTHER "TICK"
>;END IFN FTKL10
	SOJG	T1,OPRFI1	;LOOP FOR WHOLE TIME
OPRFI2:	POP	P,T1		;--
LCPOPJ:	POPJ	P,		;LOCAL CPOPJ FOR USE WHEN HISEG ISN'T MAPPED
	$HIGH			;BACK TO THE HIGH SEGMENT
;ROUTINE TO FIND A FREE TTY DEVICE DATA BLOCK ;⊗ DDBSRC DDBSR0 DDBSRA DDBSR1

;CALL FROM CLOCK LEVEL TO DO AN ATTACH ON A NEW JOB, OR
;FROM UUO LEVEL ON AN INIT OF A NEW LINE.

;CALL:	NO ARGUMENTS
;	PUSHJ P,DDBSRC
;	  ERROR RETURN		;NONE AVAILABLE. F=0. T1 CLOBBERED
;	OK RETURN		;ADDRESS IN F, TTYUSE SET IN DEVMOD
;				;RESPECTS J,U,T2.
;				;IF YOU DECIDE NOT TO USE DDB, YOU BETTER
;				;FREE IT UP AGAIN.


DDBSRC:	PUSHJ	P,DDBSR0	;TRY TO GET A DDB
	  SKIPA			;LOST -- TRY AGAIN
	PJRST	CPOPJ1##	;WE WON
DDBSR0:	MOVEI	F,TTYLST	;START OF THE TTY DDB'S
DDBSRA:	MOVSI	T1,TTYUSE	;FLAG THAT A DDB ISN'T FREE
	SCNOFF			;MAKE SURE NO CONFLICT HERE
	TDNN	T1,DEVMOD(F)	;IS THIS DDB FREE?
	JRST	DDBSR1		;YES. GO GRAB IT.
	SCNON			;NO. REENABLE PI SYSTEM
	HLRZ	F,DEVSER(F)	;LINK DOWN THE DDB CHAIN
	MOVE	T1,DEVMOD(F)	;MAKE SURE STILL A TTY DDB
	TLNE	T1,DVTTY	;IS IT?
	JUMPN	F,DDBSRA	;YES. (UNLESS END OF CHAIN)
	MOVEI	F,0		;NO MORE TTY DDB'S. WE LOSE.
	POPJ	P,0		;RETURN NON-SKIP, WITH 0 IN DDB

DDBSR1:	IORM	T1,DEVMOD(F)	;SET BIT SO WE HAVE THE DDB
	SCNON			;NOW PI'S CAN HAPPEN AGAIN
	PUSHJ	P,CLRDVL##	;CLEAR JOB NO. IN CASE OF JUNK
	MOVE	T1,[XWD TTYATC,ASSCON+ASSPRG]	;LIKEWISE MODE BITS
	ANDCAM	T1,DEVMOD(F)	; ..
	MOVSI	T1,DEPRAS	;GET THE RESTRICTED ASSIGN BIT
	ANDCAM	T1,DEVSTA(F)	;MAKE SURE IT'S CLEARED
	SETZM	DEVLOG(F)	;AND LOGICAL NAME
	MOVSI	T1,IOFST	;AND INITIAL S WORD
	MOVEM	T1,DEVIOS(F)	;WHICH SHOULD LEAVE IT PRETTY CLEAN
	JRST	CPOPJ1##	;SKIP RETURN. WE HAVE A DDB.

;ROUTINE TO FIND A TTY DDB WHICH IS ATTACHED TO, I.E. ;⊗ TTYSRC
;CONTROLLING, A PARTICULAR JOB NUMBER.
;
;CALLED AT COMMAND LEVEL BY ATTACH COMMAND, AND AT UUO LEVEL
;BY REFERENCES TO DEVICE "TTY" OR TTCALLS, ETC.
;
;CALL:	MOVE J,JOB NUMBER DESIRED
;	PUSHJ P,TTYSRC
;	  ERROR RETURN.	;NOT FOUND. AC'S U,F,S NOT GUARANTEED
;	NORMAL RETURN	;U, S AND F SET UP. NOTE THAT THIS DOES
;			;!NOT! IMPLY THAT ANYONE IS ATTACHED. THAT IS,
;			; U MAY CONTAIN A ZERO
;
;			;CLOBBERS T1

TTYSRC::JUMPLE	J,CPOPJ##	;NOBODY CONTROLS JOB ZERO. YOU ARE CONFUSED.
	HRRZ	F,TTYTAB##(J)	;GET CONTROLLING TTY DDB ADDRESS
	JUMPE	F,CPOPJ##	;RETURN IF NONE
	MOVE	T1,DEVMOD(F)	;GET DEVICE BITS FROM DDB
	TLNN	T1,TTYATC	;IS THIS THE CONTROLLING TTY?
	POPJ	P,0		;NO. IT WAS A SLAVE OR SOMETHING.
	HRRZ	U,DDBLDB(F)	;YES. GET THE LDB LINK (MAY BE 0)
	MOVE	S,DEVIOS(F)	;AND I/O STATUS WORD
	JRST	CPOPJ1##	;GIVE SUCCESS RETURN.
;ROUTINE CALLED WHEN DEVSRC CAN'T FIND DEVICE XXX (IN T1), AND ;⊗ GETDDB GETDB5 CHKFLN
; IT WANTS TO SEE IF IT IS A PHYSICAL TTY. GETDDB CHECKS NAME,
; AND IF IT SHOULD BE A TTY, LOOKS FOR ITS DDB, OR MAKES ONE.
;
;CALL:	MOVE J,JOBNUMBER
;	MOVE T1,SIXBIT DEVICE NAME, ALLEGEDLY A PHYSICAL TTY NAME
;	PUSHJ P,GETDDB
;	  ERROR RETURN, NOT A TTY OR THERE ARE NO DDB'S AVAILABLE.
;	OK RETURN. IT IS A TTY, AND F AND U ARE NOW SET TO IT.
;RESPECTS T1 ON THE OK RETURN ONLY
;
;CALLED FROM DEVSRC, SO MAY BE AT UUO OR CLOCK LEVEL

GETDDB::
IFN FTMP,<
	PUSHJ	P,INTLVL##	;IF AT UUO LEVEL
	  PUSHJ	P,ONCPU0##	;AVOID RACES WITH COMCON
>
	PUSHJ	P,TTYPHY	;LOOK FOR THIS PHYSICAL NAME
	  POPJ	P,0		;IT ISNT A TTY
	JUMPN	F,GETDB5	;IS THERE A DDB ALREADY?
				;IF SO, SOMEONE HAS CALLED GETDDB WHO
				; COULD HAVE CALLED DEVSRC.
	PUSHJ	P,CHKFLN	;CHECK FOR LEGAL ACCESS TO FRCLIN
	PUSHJ	P,DDBSRC	;NO. NEED A NEW DDB. TRY TO GET ONE.
	  POPJ	P,0		;NONE AVAILABLE. FAIL RETURN
	HRRM	F,LDBDDB(U)	;SUCCESS. SET LINKS TO AND FROM DDB
	HRRM	U,DDBLDB(F)	; AND LINE DATA BLOCK.
	PUSHJ	P,SCNNAM	;FILL IN REAL NAME AND PUNIT
IFN FTNET,<PUSHJ P,SETSTA>	;PUT STA # IN DDB
GETDB5:	MOVE	T1,DEVNAM(F)	;RESTORE REAL NAME TO T1
	JRST	CPOPJ1##	;AND GIVE SUCCESSFUL RETURN FROM GETDDB


;ROUTINE TO CHECK FOR LEGAL ACCESS TO FRCLIN.
;CALL:	MOVE	U,LDB ADDRESS
;	PUSHJ	P,CHKFLN
;	  RETURN HERE IF NOT FRCLIN OR LEGAL ACCESS
;	  RETURN HERE IF ACCESS NOT LEGAL
;DESTROYS T1

CHKFLN:	LDB	T1,LDPLNO	;GET LINE NUMBER
	CAIE	T1,FRCLIN##	;IS IT FRCLIN?
	POPJ	P,		;NO, GIVE OK RETURN
	PUSHJ	P,SAVT##	;SAVE T1-T4 FOR SAFETY
	MOVSI	T1,JP.POK	;MUST HAVE POKE PRIVILEGE OR BE
	PJRST	PRVBIT##	;BE LOGGED INTO [1,2] OR JACCT
;SUBROUTINE TO PUT PHYSICAL NAME INTO T2 FOR U WHOSE LDB IS IN U ;⊗ TTYNAM
;EVEN THOUGH THERE MAY BE NOTHING IN F OR LDBDDB

TTYNAM::PUSH	P,[SIXBIT /CTY/];SEE IF CTY
	MOVEI	T1,LDRCTY
	TDNE	T1,LDBDCH(U)
	JRST	T2POPJ##	;YES.
	LDB	T1,LDPLNO
	MOVSI	T3,'TTY'	;NO. CHANGE TO TTY
	MOVEM	T3,0(P)		;ON STACK
	MOVSI	T3,(POINT 6,0,17) ;SETUP SIXBIT BYTE POINTER TO
	HRRI	T3,0(P)		;NAME ON THE STACK
	PUSHJ	P,SCNNMR	;AND CALL SAME ROUTINE AS SCNNAM DOES
	PJRST	T2POPJ##	;PUT ANSWER IN T2
				;AND RETURN FROM TTYNAM
;SUBROUTINE TO FIND LDB FOR A PHYSICAL NAME, IF ITS A TTY ;⊗ TTYPHX TTYPH4 TTYPH2 TTYPH1 TTYPHY TTYPHZ TTYALL
;AND LOAD F WITH LINKED DATA BLOCK, IF ANY, BUT DON'T MAKE ONE IF NONE YET
;SKIP RETURN IF ITS A TTY


TTYPHX:	PUSHJ	P,TSTOPR##	;SEE IF OPR AND FUDGE T1
	PUSHJ	P,SAVE2##
	PUSH	P,T1		;SAVE NAME
	MOVE	P1,BOOTCT##
	CAMN	T1,[SIXBIT /CTY/] ;IS CTY WANTED?
	JRST	TTYPH1		;YES. GO USE TCONLN
	HLLZ	P1,T1		;GET FIRST THREE CHARACTERS
	CAMN	P1,[SIXBIT /TTY/] ;ARE THEY TTY?
	TRNN	T1,770000	;AND ALSO IS FOURTH CHAR NON-BLANK?
	PJRST	TPOPJ##		;NO. NOT A LEGAL NAME.
	MOVSI	P2,(<POINT 6,0(P),17>)	;POINTER TO READ CHARS
	MOVEI	P1,0		;INITIALIZE LINE TO 0
TTYPH4:	ILDB	T1,P2		;GET A SIXBIT CHARACTER FROM NAME
	JUMPE	T1,TTYPH2	;JUMP IF END OF NAME.
	TRC	T1,"0"-40	;CONVERT SIXBIT TO BINARY
	CAILE	T1,7		;IS IT AN OCTAL DIGIT?
	JRST	TPOPJ##		;NO. BAD CHAR IN NAME
	ASH	P1,3		;MULTIPLY BY 8
	ADDI	P1,0(T1)	;ADD IN THIS DIGIT
	TLNE	P2,770000	;CHECK FOR MORE DIGITS
	JRST	TTYPH4		;LOOP FOR MORE DIGITS
TTYPH2:	CAMLE	P1,P3		;IS IT A LEGAL HARDWARE LINE #?
	JRST	TPOPJ##		;NO. TOO BAD.
TTYPH1:	HRRZ	U,LINTAB##(P1)	;GET LINE DATA BLOCK ADDRESS
	HRRZ	F,LDBDDB(U)	;GET ATTACHED DDB, IF ANY.
	JRST	TPOPJ1##	;GOOD RETURN

TTYPHY::PUSH	P,P3		;SET UP FOR PHYSICAL ONLY
	MOVEI	P3,TCONLN##
TTYPHZ:	PUSHJ	P,TTYPHX	;CALL COMMON SUBROUTINE
	  SOS	-1(P)		;REMEMBER NON-SKIP RETURN
	POP	P,P3		;BY PROPAGATING IT
	JRST	CPOPJ1##

TTYALL::PUSH	P,P3		;TRY ALLL-PHYSICAL & VIRTUAL
	MOVEI	P3,TTPLEN##-1
	JRST	TTYPHZ
;SUBROUTINE TO FIND TTY FOR A JOB IN J (TTYFND) OR FOR ;⊗ TTYFNU TTYFND TTYFNX TTYFUW TOWAIT TOWAT1 TOWAT2 PTSTRT
; CURRENT JOB (TTYFNU)
;RETURN WITH F AND U SET UP.
;GOES TO ERROR IF NO TTYDDB FOR THE JOB.


TTYFNU::MOVE	J,.CPJOB##	;GET CURRENT UUO LEVEL JOB NUMBER
TTYFND::PUSHJ	P,TTYSRC	;FIND THE JOB'S TTY DDB, ALSO U AND S
	  STOPCD CPOPJ##,DEBUG,NDJ,	;++NO DDB FOR JOB
TTYFNX:	POPJ	P,0		;SUCCESS. RETURN.

;SUBROUTINE TTYFUW (TELETYPE FIND FOR CURRENT USER AND WAIT), TO
;FIND CURRENT USER'S TTY AND WAIT FOR IT TO COME OUT OF OUTPUT
;WAIT, AND BE ATTACHED.
;SUBROUTINE TOWAIT, TO WAIT FOR TYPEOUT ACTIVITY TO (NEARLY) COMPLETE,
;IF NECESSARY.


TTYFUW::PUSHJ	P,TTYFNU	;FIND USER'S TTY
	PUSHJ	P,CKATTO	;CHECK THAT IT'S ATTACH. WAIT IF NOT.
IFN FTMIC,<			;IF MIC
	MOVE	T1,LDBMIC(U)
	TLNE	T1,LDLRSP!LDLRSY
	POPJ	P,0		;IF HE WANTS RESPONSE STUFF DO NOT TO
> ;END OF IF MIC
;ROUTINE TO WAIT FOR NEARLY EMPTY OUTPUT BUFFER. CALL ONLY AT UUO LEVEL
TOWAIT:	MOVE	S,[XWD	TTYOUW+IO+IOW,IOACT]	;SET ACTIVE & WAITING FIRST TO AVOID COMPLETION
	IORM	S,DEVIOS(F)	;BETWEEN TEST FOR COMPLETION & IOACT SET
	MOVE	T1,LDBTOC(U)	;GET COUNT OF TYPE-OUT CHARACTERS WAITING.
	CAIL	T1,10		;OVER 7?
	JRST	TOWAT2		;YES. HAVE TO WAIT
	ANDCAB	S,DEVIOS(F)	;NO. NOT WAITING, SO TURN OFF BITS
	POPJ	P,		;& RETURN
TOWAT1:	MOVE	S,[XWD TTYOUW+IO,IOACT]	;FLAG OUTPUT WAIT ACTIVITY
TOWAT2:	IORB	S,DEVIOS(F)	;IN THE DEVICE DATA BLOCK
	PUSHJ	P,PTSTRT	;WAKE UP SUBJOB, IF ANY
	PUSHJ	P,WSYNC##	;WAIT FOR IO TO COMPLETE
	HRRZ	U,DDBLDB(F)	;SET UP LDB IN CASE DETACH/ATTACHAPPENED WHILE WAITING
	JUMPE	U,[MOVE   U,DEVMOD(F)	;LDB PTR GONE, GET STATUS WORD
		   TLNE   U,TTYATC	;WAS THIS THE CONTROLLING TTY?
		   JRST   TTYFUW	;YES, GO LOOK FOR IT
		   MOVSI  S,TTYOUW+IO+IOW	;GET IO BITS
		   ANDCAB S,DEVIOS(F)		;AND CLEAR THEM
		   SETZ   U,		;NOTE NO TTY FOR THE DDB
		   POPJ   P,]		;RETURN WITH IODERR SET
	POPJ	P,		;AND RETURN


PTSTRT:	JUMPE	U,CPOPJ##	;IN CASE U NOT SET UP
	MOVEI	T1,LDRPTY	;GET PTY BIT
	TDNE	T1,LDBDCH(U)	;IS THIS ONE
	PJRST	PTYPE##		;YES, WAKE UP CONTROLLER
	POPJ	P,		;NO, RETURN
;SUBROUTINE TTYERP TO FIND TTY DDB FOR A MONITOR ERROR MESSAGE. ;⊗ TTYERP TTYERO TTYERX CKATTI CKATT0 CKATIW CKATI1 CKATI2
;CALL WITH J SET TO JOB NUMBER TO BE TYPED AT.
;IF JOB IS ZERO, OR IF DESIRED JOB IS DETACHED, TTYERP RETURNS
;WITH U SET TO OPERATOR'S CONSOLE, AND F SET FROM IT,
;BUT OF COURSE THAT DDB MAY BE ZERO, SINCE MAY BE NO JOB AT OPR.


TTYERP::PUSHJ	P,TTYSRC	;FIND THE TTY DDB IF POSSIBLE
	  JRST TTYERO		;NONE THERE. MAYBE JOB 0. GO FIND OPR
	JUMPN	U,CPOPJ1##	;SKIP RETURN TO SIGNAL LDB FOUND
TTYERO:	SKIPN	U,OPRLDB##	;GET OPERATOR LINE FROM ONCE
	STOPCD	CPOPJ##,DEBUG,NOT,	;++NO OPR TTY
	HRRZ	F,LDBDDB(U)	;GET DDB ADR, IF ANY.
TTYERX:	POPJ	P,0		;AND RETURN FROM TTYERP


;SUBROUTINES TO SET UP LINE AND MAKE SURE ATTACHED.
;CALL WITH DDB SET UP, FROM UUO LEVEL ONLY.
;RETURN WHEN ATTACHED AND AT USER LEVEL, WITH LINE SET UP.

;ONE ROUTINE FOR INPUT, ONE FOR OUTPUT, ONE FOR OUTPUT AND USER LEVEL

CKATTI:
IFN FTRSP,<PUSHJ P,RSPTIR##>	;RECORD RESPONSE SATISFIED BY TTY INPUT UUO
CKATT0:	MOVSI	S,IO		;INDICATE INPUT
	ANDCAB	S,DEVIOS(F)	;SET UP STATUS WORD
	HRRZ	U,DDBLDB(F)	;GET LINE BLOCK ADDR
	JUMPN	U,CKATI1	;IF THERE, GO ON
CKATIW:	MOVSI	S,IO+TTYOUW	;MUST WAIT FOR ATTACH
	ANDCAM	S,DEVIOS(F)	;CLEAR DIRECTION BIT
	MOVEI	S,IOACT		;AND SET WAIT BIT FOR INPUT
	IORB	S,DEVIOS(F)	; ..
	PUSHJ	P,WSYNC##	;WAIT FOR ATTACH
	JRST	CKATT0		;GET LINE SET UP AND RETURN.

CKATI1:	MOVE	T1,DEVMOD(F)	;SEE IF TTY IS CONTROLLING JOB.
	TLNE	T1,TTYATC
	JRST	CKATI2		;YES.
	MOVSI	T1,LDLCOM	;NO. MAKE IT BE
	ANDCAM	T1,LDBDCH(U)	;AT USER LEVEL
CKATI2:	HLL	U,LDBDCH(U)	;GET DEVICE BITS
	TLNE	U,LDLCOM	;AT COMMAND LEVEL?
	JRST	CKATIW		;YES. CAN'T DO INPUT.
	PUSHJ	P,TYIEAT	;NO. SKIP ANY COMMANDS
	PJRST	UUOLDB		;AND GO ADJUST LINE BITS.

CKATOU:	PUSHJ	P,CKATTO	;FIRST MAKE SURE A LINE ATTACHED TO DDB ;⊗ CKATOU CKATTO CKATOW CKATO1 UUOLDB UUOLD1 UUOLD2
	TLNN	U,LDLCOM	;IS LINE AT COMMAND LEVEL?
	POPJ	P,0		;NO. USER LEVEL. RETURN.
	MOVE	T1,DEVMOD(F)	;COMMAND LEVEL.  SEE IF CONTROLLER OR I/O DEVICE
	TLNN	T1,TTYATC	;..
	POPJ	P,0		;I/O DEVICE.  LET IT THROUGH.
	PUSHJ	P,TOWAT1	;CONTROLLER.  WAIT SO DON'T CLOBBER COMMANDS
	JRST	CKATOU		;THEN TRY AGAIN FOR USER LEVEL

CKATTO:	MOVSI	S,IO		;INDICATE OUTPUT
	IORB	S,DEVIOS(F)	;SET UP STATUS WORD
	HRRZ	U,DDBLDB(F)	;GET LINE ADDR IF ANY
	JUMPN	U,CKATO1	;IF HAVE ONE, SEE IF TOP LEVEL
CKATOW:	PUSHJ	P,TOWAT1	;WAIT FOR OUTPUT DONE. (WHICH
				; IS FORCED ON ATTACH)
	JRST	CKATTO		;AND SET UP LINE, TO RETURN.
CKATO1:	HLL	U,LDBDCH(U)	;GET LINE DESCRIPTOR BITS
;	PJRST UUOLDB		;FALL INTO UUOLDB

UUOLDB::MOVEI	T1,0		;MAKE LDB AGREE WITH S
	MOVE	T2,LDBDCH(U)	;REMEMBER OLD CHARACTERISTICS
	TRNE	S,IOSTEC	;TRUTH-IN-ECHOING SET?
	TLO	T1,LDLDLR	; YES
	TRNE	S,IOSFCS	;FULL-CHARACTER-SET SET?
	TLO	T1,LDLFCS	; YES
	TRNE	S,PIMMOD	;IS THIS PACKED IMAGE MODE?
	TLOA	T1,LDLPIM	; YES, SET FLAG IN LDB (AND FORCE NO ECHO)
	TRNE	S,IOSNEC	;NO ECHO BY PROGRAM?
	TLO	T1,LDLNEC	; YES
;THIS SHOULD NO LONGER BE NEEDED, ONLY TT?CHK SHOULD SET/CLEAR IT
;	TRNE	S,IOSBKA	;SINGLE CHARACTER MODE?
;	TLO	T1,LDLBKA	; YES
	IORM	T1,LDBDCH(U)	;SET THOSE NEEDING SETTING
;	TLC	T1,LDLNEC+LDLFCS+LDLDLR+LDLBKA+LDLPIM
	TLC	T1,LDLNEC+LDLFCS+LDLDLR+LDLPIM
	ANDCAB	T1,LDBDCH(U)	;AND CLEAR THE OTHERS

IFN FTCIMP,<			;[arpa]
	TRNN	T2,LDRIMP	;[arpa] IS THIS AN IMP?
	  JRST	UUOLD2		;[arpa] NO, DON'T MESS
	PUSH	P,T3		;[arpa] YES - SAVE ANOTHER AC
	MOVE	T3,T1		;[arpa] SEE IF LDLNEC CHANGED (1 AFTER XOR)
	XOR	T3,T2		;[arpa] XOR IN OLD BITS
	TLNN	T3,LDLNEC	;[arpa]
	  JRST	UUOLD1		;[arpa] ZERO, DIDN'T CHANGE
	PUSH	P,T2		;[arpa] SAVE SOME AC'S
	PUSH	P,T1		;[arpa]
	MOVEI	T3,400+.TNIAC##	;[arpa]
	PUSHJ	P,CCTYO9	;[arpa] SEND TELNET CONTROL/ESCAPE
	MOVE	T3,LDBDCH(U)	;[arpa] GET CURRENT STATE OF NO-ECHO
	TLNN	T3,LDLNEC	;[arpa] IF ON, TRY TO DO IT, BUT...
	  SKIPA	T3,[400+.TNWNT##] ;[arpa] (ON: LET THE OTHER GUY DO IT)
	MOVEI	T3,400+.TNWIL##	;[arpa] (OFF:) ...DON'T SAY THAT WE WILL DO IT
	PUSHJ	P,CCTYO9	;[arpa] SEND WHATEVER DECIDED ON
	MOVEI	T3,400+.TOECH##	;[arpa] FOLLOW WITH ECHO NEGOTIATION CODE
	PUSHJ	P,CCTYO9	;[arpa] AND SEND THAT TOO
	POP	P,T1		;[arpa]
	POP	P,T2		;[arpa] RESCUE OPERATIONS
UUOLD1:	POP	P,T3		;[arpa] RESCUE THE STACK
UUOLD2:				;[arpa]
> ;[arpa] END FTCIMP
	CAME	T2,T1		;DON'T SEND STATUS IF NO CHANGE
	PJRST	SETCHP		;NOTE THAT TERMINAL CHARACTERISTICS CHANGED
	POPJ	P,		;NO CHANGE
;HERE FROM UUOCON WHEN A TTY HAS BEEN INITED. ;⊗ TTYOPN

TTYOPN::HRRZ	U,DDBLDB(F)	;GET LDB ADDRESS
	JUMPE	U,TPOPJ1##	;FORGET IT IF DETACHED
	MOVSI	T2,LDLCOM	;GET COMMAND LEVEL BIT
	MOVSI	T1,TTYATC	;IS TTY CONTROLLING THE JOB?
	TDNN	T1,DEVMOD(F)	;OR IS IT AN I/O DEVICE?
	ANDCAM	T2,LDBDCH(U)	;I/O PUT IT AT USER LEVEL
	PUSHJ	P,UUOLDB	;SETUP THE LDB FROM S
	PUSHJ	P,SETCHP	;MAKE SURE THE FRONT END KNOWS ABOUT THIS
	JRST	TPOPJ1##	;AND RETURN
;TWAITI  --  WAIT FOR INPUT (CHARACTER OR LINE MODE) ;⊗ TWAITI TWAITL TWATL1 TWATLK TWAITC

TWAITI:	TRNE	S,IOSBKA	;BREAK ON ALL CHARACTERS?
	JRST	TWAITC		;YES, WAIT FOR A SINGLE CHARACTER
				;FALL INTO TWAITL (EVEN FOR IMAGE MODES)

;TWAITL  --  WAIT FOR AN INPUT LINE

TWAITL:
IFN FTTVP,<
	SKIPG	LDBTOC(U)	;IF NO OUTPUT IN PROGRESS,
	PUSHJ	P,CLRPCT	;RESET THE "STOP" LINE COUNTER
> ;END IFN FTTVP
	PUSHJ	P,CKATTI	;FIRST WAIT FOR ATTACH. SET DDB AND LINE
	PUSHJ	P,TTLCHK	;CHECK FOR A LINE BEING PRESENT
	  JRST	TWATLK		;BE SURE
	POPJ	P,		;LINE PRESENT, RETURN

TWATL1:	PUSHJ	P,TIWAIT	;NO. GO WAIT FOR ONE.
	TRNE	S,IODERR	;GOT A ↑C?
	POPJ	P,		;YES, LINE PRESENT
	PUSHJ	P,CKATTI	;MAKE SURE DIDN'T DETACH DURING WAIT
	PUSHJ	P,TTLCHK
	  JRST	TWATLK
	POPJ	P,

TWATLK:	MOVE	S,[XWD IOW,IOACT]	;FLAG ACTIVE AND WAITING SO
	IORB	S,DEVIOS(F)	;INTERRUPT WILL NOT FIND HIM ACTIVE
	PUSHJ	P,TTLCHK	;BUT NOT WAITING.  THEN LOOK AGAIN
	  JRST	TWATL1		;NOTHING ARRIVED SINCE LAST TEST
	MOVE	S,[XWD IOW,IOACT]	;SOMETHING DID SNEAK IN!
	ANDCAB	S,DEVIOS(F)	;SO FORGET ABOUT WAITING
	POPJ	P,



;SUBROUTINE TO WAIT FOR SINGLE CHARACTER INPUT

TWAITC:
IFN FTTVP,<PUSHJ P,CLRPCT>	;CLEAR LINE COUNT FOR AUTO-PAGE MODE
	PUSHJ	P,CKATTI	;MAKE SURE ATTACHED
	PUSHJ	P,TTCCHK	;CHECK FOR A CHARACTER PRESENT
	  SKIPA			;NONE PRESENT, GO WAIT
	POPJ	P,0		;YES. RETURN
	MOVE	S,[XWD	IOW,IOACT]	;SET BOTH ON TO AVOID RACE WITH COMPLETION
	IORB	S,DEVIOS(F)	;SO NOT GO INTO TI WITH SOMETHING THERE
	PUSHJ	P,TIWAIT	;NO. GO WAIT FOR ONE
	TRNE	S,IODERR	;GOT A ↑C?
	POPJ	P,		;YES, THAT'S ENOUGH
	JRST	TWAITC		;MAKE SURE ONE THERE IN CASE OF ↑C
;TTICHK  --  CHECK IF ANY INPUT IS AVAILABLE, LINE OR CHARACTER MODE ;⊗ TTICHK TTLCHK TTLCK2 TTCCHK
;CALL IS:
;
;	PUSHJ	P,TTICHK
;	  NO INPUT AVAILABLE
;	INPUT IS AVAILABLE
;
;THE CALLER MUST SETUP U, F, AND S APPROPRIATELY (TTLCHK AND TTCCHK
;DON'T REQUIRE F AND S, BUT TTICHK DOES).
;
;TTLCHK IS THE ROUTINE THAT HANDLES REGULAR ASCII LINE MODE, AS
;AS THE IMAGE MODES, TTCCHK HANDLES ASCII CHARACTER MODE.

TTICHK:	TRNE	S,IOSBKA	;BREAK ON ALL CHARACTERS MODE?
	JRST	TTCCHK		;YES, LOOK FOR JUST A SINGLE CHARACTER
				;NO, FALL INTO TTLCHK (EVEN FOR IMAGE MODES)

;TTLCHK  --  CHECK IF AN INPUT "LINE" IS AVAILABLE

TTLCHK::MOVSI	T1,LDLBKA	;CLEAR BREAK ON ALL CHARACTERS BIT
	ANDCAM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
TTLCK2:	TRNN	F,-1		;DO WE REALLY HAVE A DDB?
	SETZ	S,		;NO DDB, NO I/O STATUS
	SKIPLE	T1,LDBTIC(U)	;ANY INPUTTABLE CHARACTERS?
	TRNN	S,I!PIMMOD	;YES, IMAGE MODE OF SOME SORT?
	SKIPLE	LDBBKC(U)	;LINE MODE, ANY LINES AVAILABLE?
	JRST	CPOPJ1##	;INPUT AVAILABLE
	CAIL	T1,↑D70		;NO LINES, GOT LOTS OF CHARACTERS?
	JRST	CPOPJ1##	;YES, CLOSE ENOUGH, WAKE UP USER
	TLNE	U,LDLIMI	;NO. IMAGE INPUT STATE?
	TLNN	S,FRCEND	;YES. ALSO TIMED OUT?
	PJRST	STRTDL		;ECHO ONE DEFERRED LINE IF NEEDED
	JRST	CPOPJ1##	;IMAGE TIME OUT, WAKE UP HIGHER-UPS

;TTCCHK  --  CHECK IF  AN ASCII CHARACTER IS AVAILABLE

TTCCHK:	MOVSI	T1,LDLBKA	;SET "BREAK ON ALL CHARACTERS" BIT
	IORM	T1,LDBDCH(U)	;IN LINE DATA BLOCK
	SKIPLE	LDBTIC(U)	;IS THERE A CHARACTER ALREADY?
	JRST	CPOPJ1##	;YES, SKIP RETURN
	PJRST	STRTDC		;NO, ECHO ONE DEFERRED CHARACTER IF NEEDED
;SUBROUTINE TIWAIT TO WAIT FOR SOME INPUT, AND SEND XON IF NEEDED. ;⊗ TIWAIT STRTDC STRTDL STRTDE

TIWAIT:
IFN FTMIC,<			;IF MIC
	SKIPE	LDBMIC(U)	;MIC RUNNING FOR THIS LINE?
	PUSHJ	P,MICWAK	;YES, WAKE MIC IF NECESSARY
> ;END OF IF MIC
	MOVEI	T1,LDRPTY	;IS THIS LINE PTY-DRIVEN?
	TDNE	T1,LDBDCH(U)	;CHECK	IN THE LDB CHARACTERISTICS
	PUSHJ	P,PTYOW##	;YES. GO MARK THIS WAIT.
IFN FTCAFE,<IFN FT2741!FTNET,<	;IF WE SUPPORT 2741'S ON THE DC76
	PUSHJ	P,UNLKBD	;UNLOCK KEYBOARD
> ;END FT2741
> ;END FTCAFE
	MOVSI	S,IO+TTYOUW	;MARK DIRECTION AS INPUT.
	ANDCAB	S,DEVIOS(F)	;CLEAR IN CORE
	MOVEI	T1,IMGTIM	;TIMEOUT FOR IMAGE MODE
	TRNE	S,I		;TERMINAL IN IMAGE MODE?
	DPB	T1,LDPTIM	;YES. STORE TIMEOUT TIME
	PUSHJ	P,CHKXON	;SEND X-ON IF NEEDED
	JRST	WSYNC##		;WAIT FOR INPUT



;SUBROUTINE TO START DEFERRED ECHO
;CALL
;	MOVEI	T2,BIT (EITHER L1RDEL FOR LINE OR L1RDEC FOR CHARACTER)
;	PUSHJ	P,STRTDE
;	<ALWAYS RETURNS HERE>

STRTDC::MOVEI	T2,L1RDEC	;THE ALLOW-ONE-CHARACTER-TO-ECHO BIT
	TDNN	T2,LDBBYT(U)	;IS IT ALREADY SET, OR
	SKIPLE	LDBTIC(U)	;ARE ANY CHARACTERS AVAILABLE?
	POPJ	P,		;YES, DON'T ECHO ANY MORE
	JRST	STRTDE		;COMMON CODE

STRTDL::MOVEI	T2,L1RDEL	;THE ALLOW-ONE-LINE-TO-ECHO BIT
	TDNN	T2,LDBBYT(U)	;IS IT ALREADY SET, OR
	SKIPLE	LDBBKC(U)	;ARE ANY LINES AVAILABLE?
	POPJ	P,		;YES, DON'T ECHO ANY MORE

STRTDE::IORM	T2,LDBBYT(U)	;SET BIT ALLOWING LINE OR CHARACTER
	MOVEI	T2,L1RDEM	;GET DEFERRED ECHO MODE BIT
	TDNE	T2,LDBBYT(U)	;DEFERRED?
	SKIPG	LDBECC(U)	;AND INPUT WAITING?
	PJRST	CHKXON		;NOT DEFERRED, OR NO INPUT WAITING
				; MAKE SURE WE ARE ACCEPTING INPUT
	PJRST	TOPOKE		;GET OUTPUT STARTED
;ROUTINE TO CHECK IF AN XOFF HAS BEEN SENT OUT ;⊗ CHKXON CHKXN1 CLRTI CLRTI1
;AND IF SO, TO SEND AN XON.
;CALLED BY:
;	PUSHJ	P,CHKXON
;	RETURN HERE ALWAYS (CLOBBERS T1,T3)


CHKXON::MOVSI	T1,LPLXOF	;IS PAGE MODE ENABLED?
	TDNN	T1,LDBPAG(U)	;GUARANTEE XON IF TALKING TO
				;ANOTHER COMPUTER
	POPJ	P,		;XON IS NOT NEEDED

CHKXN1:	MOVE	T1,LDBTIC(U)	;GET # OF INPUT CHARS
	ADD	T1,LDBECC(U)	;PLUS THOSE TO BE ECHOED
	CAILE	T1,↑D80		;TOO MANY?
	POPJ	P,		;YES, GO AWAY
	MOVSI	T1,LPLXOF	;CLEAR XOFF BIT
	ANDCAM	T1,LDBPAG(U)	;SO ONLY ONE XON IS SENT
	MOVE	T2,FLPXON	;GET POINTER TO XON
	PUSHJ	P,SETXNP	;NOTE THAT WE HAVE FILLERS
	PJRST	TOPOKE		;START TERMINAL MOVING
				;IFN FTTPAG

;ROUTINE TO GET DDB OUT OF TI WAIT IF NEEDED
;CALLED BY:
;	MOVE	J,JOB #
;	PUSHJ	P,CLRTI
;	RETURN	HERE
;RESPECTS	T1,T2
CLRTI::	PUSH	P,T1		;SAVE SOME AC'S
	PUSH	P,T2
	LDB	T1,PJBSTS##	;GET WAIT STATE CODE
	CAIE	T1,TIOWQ##	;IN TI WAIT?
	JRST	CLRTI1		;NO--EXIT
	PUSHJ	P,TTYSRC	;FIND TTY DDB
	  JRST	CLRTI1		;NO DDB?
	MOVE	T1,[IOW,,IOACT]
	ANDCAM	T1,DEVIOS(F)
CLRTI1:	POP	P,T2
	JRST	TPOPJ##

IFE FT2741,< ;⊗ UNLKBD UNLKBD UNLKB1 TTYOFE
UNLKBD==CPOPJ##
>
IFN FT2741,<			; WITH 2741 SUPPORT
;SUBROUTINE TO UNLOCK 2741 KEYBOARD:
;CALL WITH:
;	MOVEI	U,ADDRESS-OF-LDB
;	PUSHJ	P,UNLKBD
;	RETURN HERE
UNLKBD:	MOVEI	T1,LDR2741	;SET UP 2741 BIT
	TDNE	T1,LDBDCH(U)	;...
	JRST	UNLKB1		;IF A 2741
	MOVEI	T1,L2RXON	;SET UP XON BIT
	TDNN	T1,LDBBY2(U)	;SKIP
	POPJ	P,		;IF NEITHER A 2741 OR XON SET
UNLKB1:	SKIPN	LDBBKC(U)	;DON'T GIVE UP IF HAVE BRK CHAR
	SKIPL	LDBDCH(U)	;SKIP IF NOT OUTPUT IN PROGRESS
	POPJ	P,0		;JUST RETURN
	PUSH	P,T2		;SAVE T2
	PUSH	P,T3		;AND T3
	MOVEI	T1,ISRLPC	;FUNCTION
	MOVEI	T3,<LPCUKB>B27	;SUBFUNCTION
	PUSHJ	P,@LDBISR(U)	;CALL D76INT (OR WHATEVER)
	POP	P,T3		;RESTORE T3
	PJRST	T2POPJ##	;RESTORE T2 AND RETURN
>;IFN FT2741



IFN FTMSGSER,<
;SUBROUTINE TO RETURN TTY OUTPUT FEASIBILITY FOR A MPX-CONTROLLED TTY
;CALL WITH F/ADDRESS OF TTY DDB
;RETURN WITH T1/0 IF NO OUTPUT OR 1 IF OK TO OUTPUT

TTYOFE::HRRZ	T2,DDBLDB(F)	;ADDRESS OF TTY LDB
	MOVE	T1,LDBTOC(T2)	;COUNT OF OUTPUT CHARACTERS STILL WAITING
	HLL	T1,LDBDCH	;FLAG BITS
	TDNE	T1,[LDLSTP+777740]  ;IF ↑S'ED OR MORE THAN 32 CHARACTERS
	TDZA	T1,T1		;SAY OUTPUT NOT FEASIBLE
	MOVEI	T1,1		;OTHERWISE GIVE GO AHEAD
	POPJ	P,		;RETURN TO MSGSER
> ;END IFN FTMSGSER
;ROUTINE TO PUT SIXBIT NAME IN DEVNAM(DDB), AND TO SET PUNIT. ;⊗ SCNNAM SCNNMR

;CALL:	SET DDB TO DEVICE DATA BLOCK TO RECEIVE THE NAME AND UNIT
;	SET LINE TO LINE DATA BLOCK WHERE LINE NUMBER WILL BE FOUND
;	AND SET OR CLEAR IMAGE BIT IN DEVMOD DEPENDING ON
;	WHETHER THIS LINE WILL BE PTY-DRIVEN OR NOT
;	PUSHJ P,SCNNAM
;	RETURN
;CLOBBERS T1 AND T3


SCNNAM:	PUSH	P,T2		;SAVE T2
	PUSHJ	P,TTYNAM	;BUILD NAME OF DEVICE
	MOVEM	T2,DEVNAM(F)	;STORE IN DDB
	POP	P,T2		;RESTORE T2
	LDB	T1,LDPLNO	;GET PHYSICAL LINE NUMBER
	DPB	T1,PUNIT##	;AND STORE IT IN THE DDB
	SETZM	DEVSTS(F)
	MOVEI	T3,<1←I>	;GET IMAGE MODE BIT.
	IORM	T3,DEVMOD(F)	;SET IT IN THE DDB
	MOVE	T1,LDBDCH(U)	;GET DEVICE BITS
	TRNE	T1,LDRPTY	;IS THIS A PTY?
	ANDCAM	T3,DEVMOD(F)	;YES. CLEAR THE BIT.
	POPJ	P,0		;RETURN FROM SCNNAM


;SUBSIDIARY ROUTINE TO DO RADIX PRINT TO CORE.

SCNNMR:	IDIVI	T1,10		;DEVICE NAMES ARE OCTAL
	HRLM	T1+1,0(P)	;STORE A DIGIT ON STACK
	SKIPE	T1		;NEED MORE DIGITS?
	PUSHJ	P,SCNNMR	;YES. GO MAKE THEM.
	HLRZ	T1,0(P)		;RETRIEVE A DIGIT FROM STACK
	ADDI	T1,"0"-40	;CONVERT TO SIXBIT
	IDPB	T1,T3		;STORE IN OBJECT WORD (DEVNAM)
	POPJ	P,0		;POP UP TO SCNNMR OR BACK TO SCNNAM
IFN FTNET,< ;⊗ SETSTA FNDSTA DDBRL DDBRL1 STDOPR

;ROUTINE TO LOCATE A NEW TTY DDB

SETSTA:	PUSHJ	P,FNDSTA	;FIND STATION
	DPB	T1,PDVSTA##	;PUT STA # IN DEVICE LOC FIELD
	POPJ	P,		;RETURN

FNDSTA::MOVE	T1,LDBDCH(U)	;GET TTY BITS
	TRNN	T1,LDRPTY	;TERMINAL A PTY LINE?
	JRST	DDBRL		;NO - BRANCH FOR REAL TERMINAL
	LDB	T1,LDPLNO	;YES, GET LINE NUMBER ONLY
	SUBI	T1,PTYOFS##	;DECREMENT TO PTY LINE NUMBER
	PUSH	P,F		;SAVE TTY DDB FOR A SECOND
	MOVE	F,PTYTAB##(T1)	;GET PTY DDB
	LDB	T1,PDVSTA##	;GET LOCATION OF PTY
	JRST	FPOPJ##		;RESTORE TTY DDB AND RETURN TO CALLER

DDBRL:	TRNN	T1,LDRREM	;REMOTE STATION TERMINAL?
	JRST	DDBRL1		;NO, MUST BE A LOCAL TERMINAL
	LDB	T1,LDPRNN	;YES, GET THE REMOTE NODE NUMBER
	JUMPE	T1,DDBRL1	;LOCAL(?)
	POPJ	P,		;RETURN.

DDBRL1:	MOVEI	T1,LOCSTA##	;LOCAL STATION
	POPJ	P,		;RETURN


>
;ROUTINE TO ESTABLISH DEVICE OPR IF POSSIBLE
;CALL:	MOVE	T1,DEVICE NAME
;	PUSHJ	P,STDOPR
;RETURN CPOPJ IF ILLEGAL
;SKIP RETURN WITH DEVICE CHANGED
STDOPR::PUSHJ	P,TTYPHY	;LOOK FOR THIS PHYSICAL NAME
	  POPJ	P,		;FAILED IF NOT POSSIBLE
	HRRZM	U,OPRLDB##	;SAVE NEW LDB ADDRESS
	MOVEM	T1,DEVOPR##	;SAVE NEW NAME
	JRST	NETOPR##	;TELL NETWORK THAT OPR CHANGED
	SUBTTL	ROUTINES FOR PTY ;⊗ CNTRLO PTYPUT PtyNCP PTYINA

;PTYPUT IS CALLED FROM PTYSER TO PLACE A CHARACTER IN A TERMINAL INPUT
;BUFFER AS THOUGH THE TERMINAL HAD BEEN TYPED ON. NO ECHOING IS ALLOWED,
;THOUGH AND THIS ROUTINE IS A SIMPLIFIED VERSION OF RECINT AND
;XMTECH, TO MAKE THE CHARACTERS VISIBLE TO THE CONTROLLED JOB WITHOUT ECHOING
;CALL
;	MOVE	T3,CHAR
;	MOVE	T1,CHAR BITS FROM SPCHEK
;	PUSHJ	P,PTYPUT
;	  ERROR	RETURN
;	  NORMAL RETURN

CNTRLO==17
PTYPUT::PUSHJ	P,SAVE1##	;PRESERVE P1
	MOVSI	P1,LDLFSP	;THE FULL-SCNSER-SERVICE BIT
	TDNE	P1,LDBTTW(U)	;IS THIS PTY BEING A TTY?
	JRST	PTYPT1		;YES, LET SCNSER DO CHARACTER HANDLING
	TLNE	T1,CHALT	;POSSIBLE ALTMODE?
	PUSHJ	P,RIALTO	;YES, CONVERT IF WANTED
	MOVE	P1,T1		;SAVE BITS IN P1
ifn ftcimp,<	;[arpa] incase some clown is cross patched out over a PTY.
	SKIPN	f,LDBIMP(U)	;[arpa] CROSSPATCHED TO IMP?
	  JRST	PtyNCP		;[arpa] NO.
	pushj	p,RecQuo##	;[arpa] is it something the NET wants to know?
	  pjrst	cpopj1##	;[arpa] yes, thank you.  we handled it.
				;[arpa] else not ours.  continue looking.
PtyNCP:				;[arpa] not cross patched
> ;[arpa] end of ifn FTCIMP
	CAIN	T3,CNTRLO
	PJRST	FLPCNO
IFN FTMIC,<			;IF MIC
	SKIPE	LDBMIC(U)
	CAIE	T3,1		;CONTROL A COUNTS AS ↑C TO MIC
> ;END OF IF MIC
	CAIN	T3,3		;CONTROL C?
	JRST	PTYCC		;YES. SPECIAL CHECKING
IFN FTWATCH,<
	CAIN	T3,"T"-100
	JRST	PTYCT
PTYINA:>
	MOVSI	T2,L2LCCS	;NOT CONTROL C, SO
	ANDCAM	T2,LDBBY2(U)	;CLEAR SYNC BIT
IFN FTMIC,<			;IF MIC
	SKIPE	T2,LDBMIC(U)
	JRST	PTYMCK
> ;END OF IF MIC


;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ PTYPT1

PTYPT1:	MOVE	T2,LDBTIC(U)	;IS THIS LINE ALREADY FULL?
	CAIG	T2,↑D200	; ..
	SKIPG	TTFREN##	;OR LISTS EXHAUSTED?
	POPJ	P,0		;YES. DISCARD CHAR
	SKIPN	TTFTAK		;ANY FREELIST
	POPJ	P,0		;NO--PUNT
	AOS	(P)		;GOING TO GIVE GOOD RETURN NOW
	MOVSI	T2,LDLFSP	;THE FULL-SCNSER-PTY BIT
	TDNE	T2,LDBTTW(U)	;IS THIS UNDER FULL SCNSER CONTROL?
	PJRST	RECPTY		;YES, ENTER AT THE TOP
IFN FTMIC,<			;IF MIC
	MOVE	T1,P1		;SETUP CHARACTER BITS FOR MICECH
	SKIPE	LDBMIC(U)
	PUSHJ	P,MICECH	;SAY COL1 TO MIC
> ;END OF IF MIC
	SCNOFF			;NO INTERRUPTION
	STCHK	T3,LDBTIP(U)	;STORE CHARACTER
	TLNE	P1,CHBRK	;IS THIS A BREAK CHARACTER?
	PUSHJ	P,SETBKU	;YES, STORE LAST BREAK POINTER
	LDCHK	T3,LDBECT(U)	;TAKE CHARACTER NEEDING ECHO
	TLNE	P1,CHBRK	;BREAK CHAR?
	AOS	LDBBKC(U)	;YES. COUNT BREAKS
	AOS	T2,LDBTIC(U)	;ADVANCE TYPEIN COUNT
	SCNON			;ALLOW INTERRUPTS AGAIN
	TLNE	U,LDLBKA	;TERMINAL IN BREAK-ON-ALL MODE?
	PUSHJ	P,RCVWKQ	;YES. WAKE JOB IF WAITING
	CAIG	T2,TTIBRK	;ENOUGH TO WAKE ON?
	TLNE	P1,CHBRK	;OR A BREAK CHARACTER?
	PUSHJ	P,ECHBRK	;YES. WAKE THE JOB
	POPJ	P,		;SUCCESSFUL RETURN TO PTYSER
;MORE OF PTYPUT. SPECIAL CODE FOR CONTROL C ;⊗ PTYCC PTYCC4 PTYCC1 FLPCNO PTYCT

PTYCC:
IFN FTMIC,<			;IF MIC
	SKIPE	T1,LDBMIC(U)
	PUSHJ	P,MICPRC
> ;END OF IF MIC
	PUSHJ	P,RIDLN		;YES. DO SO.
	MOVSI	T1,L2LCCS	;SECOND CONTROL C?
	TDNE	T1,LDBBY2(U)	; ..
	PUSHJ	P,CNCCHK	;YES. FORCE CONTROL C IF POSSIBLE
	  JRST	PTYCC1		;NOT SECOND--GO SET BIT
	  JRST	PTYCC4		;NO. (JACCT) JUST PASS THE CHARACTER
	PUSHJ	P,TSETBI	;YES. CLEAR BUFFERS
	PUSHJ	P,TSETBO	; ..
	JRST	CPOPJ1##

PTYCC4:	PUSHJ	P,TTHALT	;FORCE .HALT COMMAND
PTYCC1:	MOVSI	T1,L2LCCS	;SET "↑C LAST IN" BIT
	IORM	T1,LDBBY2(U)	;SET BIT FOR NEXT TIME
	JRST	PTYPT1		;AND GO STORE CONTROL C IN INPUT BUFFER


;HERE ON ↑O TO PTY

FLPCNO:	MOVEI	T1,LDROSU	;FLIP THE ↑O BIT WHEN PTY OR REMOTE
	XORM	T1,LDBDCH(U)	;SENDS ↑O
	PUSHJ	P,TSETBO	;CLEAR THE OUTPUT BUFFER
	PJRST	XMTWAK		;WAKE JOB IF IN OUTPUT WAIT
IFN FTWATCH,<
PTYCT:	PUSHJ	P,DOCTLT
	  JRST	PTYINA
	  JRST	TTFRC1
	JRST	CPOPJ1##
>
;SUBROUTINE TO SET DEFAULT TERMINAL CHARACTERSTICS ;⊗ SETTTC SETTT1
;CALLING SEQUENCE:
;	MOVEI	T1,TERMINAL TYPE
;	MOVE	U,ADDRESS OF THE LDB
;	PUSHJ	P,SETTTC
;	ALWAYS RETURN HERE

SETTTC::MOVE	T2,T1
	JUMPGE	T1,SETTT1	;CUSTOMER DEFINED TYPE ?
	MOVNS	T2		;YES
	TRO	T2,100		;CUSTOMER TYPES ARE 101-177
SETTT1:	DPB	T2,LDPTTT	;STORE TERMINAL TYPE
	LSH	T1,1		;2 WORDS PER ENTRY
	LDB	T2,TTPWID	;WIDTH
	DPB	T2,LDPWID	;STORE THAT
	LDB	T2,TTPPSZ	;PAGE SIZE
	DPB	T2,LDPPSZ	;STORE THAT
	LDB	T2,TTPFLC	;FILLER CLASS
	DPB	T2,LDPFLC	;STORE THAT
	LDB	T2,TTPFRM	;FORM FEED
	DPB	T2,LDPFRM	;STORE THAT
	LDB	T2,TTPTAB	;TABS
	DPB	T2,LDPTAB	;STORE THAT
	LDB	T2,TTPLCT	;LOWER CASE
	DPB	T2,LDPLCT	;STORE THAT
	LDB	T2,TTPALT	;ALTMODE CONVERSION
	DPB	T2,LDPALT	;STORE THAT
	LDB	T2,TTPDIS	;GET DISPLAY SETTING
	DPB	T2,LDPDIS	;STORE THAT
	POPJ	P,		;RETURN
;TWO SUBROUTINES TO INITIALIZE THE LDB. LDBCLR SETS UP THE BITS FROM ;⊗ LDBCLR LDBINI
;INITIAL STATE FOUND IN LINTAB, THEN FALLS INTO LDBINI. LDBINI JUST
;CLEARS AS REQUIRED ON 140 RESTART.
;BOTH SHOULD BE CALLED WITH LINE SET UP.

LDBCLR::LDB	T1,LDPLNO	;GET LINE NUMBER
	LDB	T1,LNPVRG	;GET VIRGIN-STATE BITS FROM LINTAB
	TRZ	T1,4		;CLEAR INITIA BIT
	DPB	T1,LDPVR2	;STORE THEM AROUND THE LDB
	LSH	T1,-5		; ..
	DPB	T1,LDPVR1	; ..
	LSH	T1,-6		; ..
	DPB	T1,LDPFLC	;LAST IS THE FILLER CLASS
	MOVSI	T1,LDLFSP	;INITIALLY UNKNOWN TERMINAL TYPE
	ANDM	T1,LDBTTW(U)
IFN FT2741,<
	LDB	T1,LDPSPD
	MOVEI	T2,LDR2741
	CAIN	T1,104
	IORM	T2,LDBDCH(U)
>;IFN FT2741
LDBINI::MOVSI	T1,LDBCMR+LDBCMK;CLEAR COMMAND REQUEST BITS
	ANDCAM	T1,LDBDDB(U)	;IN LINE DATA BLOCK
	MOVE	T1,[LDIBCM]
	ANDCAM	T1,LDBBYT(U)	;CLEAR MOST BYTES
	MOVE	T1,LDIDCM	;CLEAR DEVICE CHARACTERISTICS
	ANDCAM	T1,LDBDCH(U)	; AS APPROPRIATE
	MOVSI	T1,LDLIDL	;GET THE IDLE BIT
	IORM	T1,LDBDCH(U)	;WHICH SHOULD NORMALLY BE SET
IFN FTCIMP,<			;[arpa]
	SETZM	LDBIMP(U)	;[arpa] CLEAR IMP RELATED WORDS
	SETZM	LDBQUO(U)	;[arpa]
>				;[arpa]
	MOVEI	T1,↑D72		;INITIAL VALUE OF TERMINAL WIDTH
	DPB	T1,LDPWID	;STORE IN LDB
	MOVSI	T1,L2LCLR	;CLEAR NECESSARY BITS IN LDBBY2
	ANDCAM	T1,LDBBY2(U)	; ..
	LDB	T3,LDPLNO	;COPY LINE NUMBER
	MOVSI	T1,LDLCOM+LDLLCT;ASSUME AT COMMAND LEVEL AND UPPER CASE
IFN FTD10H,<			;CODE FOR 2741 ON DC10H
	HLRZ	T2,LINTAB##(T3)	;GET BITS FROM LINTAB
	TRNN	T2,TTVDIS##	;IS IT A DISPLAY LINE
				; WHICH INDICATES ITS A DC10H LINE?
	  JRST	.+4		;NO
	MOVSI	T2,LILCFE	;SET CLEVER BIT
	IORM	T2,LDBISR(U)	; IN THE LDB.
	TRO	T1,LDR2741	;ALSO TELL LDB ITS A 2741
>;END IFN FTD10H
IFN FTKS10,<
	MOVSI	T2,LILCFE	;CLEVER BIT
	CAIGE	T3,M.DZNL##	;IS THIS A DZ11 LINE ?
	IORM	T2,LDBISR(U)	;IS DZ11 LINE
>;IFN FTKS10

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE ;⊗ LDBIMI

IFN FTCIMP,<				;[arpa]
	CAIL	T3,ITYFST##		;[arpa] IS THIS AN ITY?
	 CAIL	T3,ITYFST##+ITYN##	;[arpa]
	  JRST	LDBIMI			;[arpa] NO
	TLZ	T1,LDLLCT		;[arpa] YES, ALWAYS LOWER CASE
	TRO	T1,LDRIMP		;[arpa] always make it an IMP
LDBIMI:					;[arpa]
>					;[arpa]
	CAMN	T3,BOOTCT##	;THIS THE CTY
	TRO	T1,LDRCTY	;YES--SET CTY BIT
	CAIN	T3,FRCLIN##	;THIS THE LINE RESERVED FOR THE MONITOR?
	TLZ	T1,LDLLCT	;YES, IT IS ALWAYS LC
;[drp] provan, march 1, 1983: PTYs should try to avoid changing anything in
;[drp]			the character stream.
	CAILE	T3,TCONLN##	;ABOVE TCONLN?
;[drp]	TRO	T1,LDRPTY	;YES. SET PTY BIT
	  tdo	t1,[xwd <ldltab!ldlfrm!ldlnfc>,ldrpty]	;[drp] set bits on
	CAILE	T3,TCONLN##	;[drp] still a pty?
	  tlz	t1,ldllct	;[drp] make it lower case, too.
	IORM	T1,LDBDCH(U)	;PUT THESE BITS IN THE LDB
	PUSHJ	P,TYOVRG	;SETUP BYTE STREAM FOR OUTPUT
	PUSHJ	P,RECVRG	;AND FOR INPUT
	PUSHJ	P,TSETBI	;YES--CLEAR INPUT BUFFER
	HRLOI	T1,LPLCLR	;CLEAR PAGE BITS
	ANDCAM	T1,LDBPAG(U)	;...
	MOVSI	T1,LPLPAG	;INITIALIZE TERMINAL TO HANDLE XON/XOFF
	IORM	T1,LDBPAG(U)	;...
	MOVSI	T1,LPLALT	;THE ALTMODE-CONVERION BIT
	XCT	TTDALT##	;IORM OR ANDCAM DEPENDING ON DEFAULT
				; FOR TERMINAL ALT (SEE COMDEV)
IFN FTMIC,<SETZM LDBMIC(U)>	;CLEAR MIC WORD
	MOVSI	T3,L1LOFL	;OFF LINE BIT
	MOVEI	T1,ISROFL
	PUSHJ	P,@LDBISR(U)
	IORM	T3,LDBOFL(U)
	POPJ	P,0		;RETURN FROM LDBINI
	subttl	ScnSer support for ARPAnet ;⊗

ifn FtCimp,<	;[arpa]

;[arpa] these are routine for the arpanet support which deal almost
;[arpa]	entirely with the SCNSER data base.  that's why they're here
;[arpa]	instead of in a arpanet module.  because they deal with the
;[arpa]	data base, they are the routines most likely to be affected
;[arpa]	but changes in ScnSer.

;[arpa]	these routines go one for several pages.

;[arpa]	still in IFN FtCImp
;[arpa]	still in IFN FtCImp ;⊗ SCNMIN SCNMN1

;[arpa] SUBROUTINE CALLED ONCE A MINUTE ON THE CLOCK TO LOOK
;[arpa] FOR LOST TELETYPE DDB'S AND RETURN THEM.  APPLIES TO IMP ITY'S AND DATASETS.
SCNMIN::MOVEI	F,TTYLST	;[arpa] POINT TO FIRST TTY DDB
SCNMN1:	PUSHJ	P,TTYKLQ	;[arpa] RETURN DDB IF LOST
	HLRZ	F,DEVSER(F)	;[arpa] ADVANCE TO NEXT DDB
	MOVE	T3,DEVMOD(F)	;[arpa] IS IT A TTY?
	TLNE	T3,DVTTY	;[arpa] ....
	  JRST	SCNMN1		;[arpa] YES - KEEP ON TRUCKING
	POPJ	P,		;[arpa] NO - EXUENT OMNI

;[arpa]	still in IFN FtCImp
;[arpa]	still in IFN FtCImp ;⊗ DSCCLR DSCCL1

;[arpa] SUBROUTINE TO CLEAR OUT LDB,DDB UPON LOSING A CONNECTION.
;[arpa]    APPLIES BOTH TO IMP AND DDB CONNECTIONS. ENTER WITH U
;[arpa]    POINTING TO DDB IN QUESTION.

DSCCLR::
	SKIPE	F,LDBIMP(U)	;[arpa] CROSSPATCHED TO IMP?
	  PUSHJ	P,TTIDET##	;[arpa] YES - PULL THE PLUG
	PUSHJ	P,LDBCLR	;[arpa] CLEAN OUT LDB STATUS
IFN FTLINK,<			;[link]
	PUSHJ	P,LNKBRK##	;[link] SHAKE OFF ANY EXISTING LINKS
>				;[link]
	PUSHJ	P,TSETBI	;[arpa] CLEAR INPUT
	PUSHJ	P,TSETBO	;[arpa]  AND OUTPUT BUFFERS
	HRRZ	F,LDBDDB(U)	;[arpa] SEE IF THERE'S A JOB
	JUMPE	F,CPOPJ##	;[arpa] NO
	MOVE	T1,DEVMOD(F)	;[arpa] MAY BE A JOB. GET MODE WORD
	TLNN	T1,TTYATC	;[arpa] IS TTY CONTROLLING A JOB?
	  POPJ	P,		;[arpa] NOT A CONTROLLING TTY
	SKIPE	T1,F
	  LDB	T1,PJOBN	;[arpa] GET JOB NUMBER
	MOVE	T2,JBTSTS##(T1)	;[arpa] GET JOB STATUS
	TLNN	T2,JLOG		;[arpa] IS JOB LOGGED IN?
	  JRST	DSCCL1		;[arpa] NO - STOP JOB BY SENDING REAL CTRL-C
	MOVEI	T3,TTFCXD	;[arpa] DETACH COMMAND INDEX
	DPB	T3,LDPCMX	;[arpa] STORE IN FORCED COMMAND INDEX BYTE
	MOVSI	T3,LDBCMR+LDBCMF ;[arpa] SET FORCED COMMAND BIT
	IORM	T3,(U)		;[arpa] FOR COMMAND SCANNER TO SEE
	AOS	COMCNT##	;[arpa] WAKE COMMAND DECODER
	PJRST	CMDSET		;[arpa] CALL COMMAND ROUTINE

;[arpa] HERE IF NOT LOGGED IN. SET ↑O BIT AND SEND ↑C, FOR PROGRAM TO
;[arpa]  INTERPRET AS IT WILL (IE, KILL LOGIN)
DSCCL1:	MOVSI	T1,LDLCOM 	;[arpa] CLEAR COM LEVEL BIT, SET ↑O BIT
	HRRI	T1,LDROSU	;[arpa]
	XORM	T1,LDBDCH(U)	;[arpa] (COM WAS SET BY LDBCLR)
	MOVEI	T3,"C"-100	;[arpa] SET UP A CTRL-C
	PJRST	RECIN1		;[arpa] JAM IT INTO INPUT

;[arpa]	still in IFN FtCImp
;[arpa]	still in IFN FtCImp ;⊗ TTYIMP TTYIM1 TTYIM2


;[arpa] ROUTINE TO SET UP A TTY-TO-IMP CROSSPATCH (THEREAFTER ADDRESSED AS
;[arpa]  HIS NASTINESS)

;[arpa] 	MOVE	F,[IMP DDB ADDRESS]
;[arpa] 	MOVE	J, JOB NUMBER
;[arpa] 	PUSHJ	P,TTYIMP##
;[arpa] 	ALWAYS RETURN HERE (NO CONNECTION MADE IF ERROR)
;[arpa] 	  RETURNS LDB POINTER IN T1

TTYIMP::PUSH	P,U		;[arpa] SAVE OLD U (NEEDED BY NCP)
	SKIPE	U,TTYTAB(J)	;[arpa] GET TTY DDB ADDRESS
	  HRRZ	U,DDBLDB(U)	;[arpa] FOLLOW POINTER TO LDB
	JUMPE	U,TTYIM2	;[arpa] FORGET IF NONEXISTENT OR DETACHED
	LDB	T1,LDPLCL##	;[arpa] GET LOCAL ESCAPE CHARACTER
	JUMPN	T1,TTYIM1	;[arpa] IS THERE ONE DEFINED?
	MOVEI	T1,037		;[arpa] NO - PREVENT USER FROM NOT BEING ABLE TO
	DPB	T1,LDPLCL##	;[arpa] TO ESCAPE BY GIVING HIM DEFAULT (↑←)
TTYIM1:	HRRZM	F,LDBIMP(U)	;[arpa] STORE IMP POINTER IN LDB
TTYIM2:	MOVEI	T1,(U)		;[arpa] COPY LDB ADDRESS INTO T1
	JRST	UPOPJ##		;[arpa] RESTORE U AND RETURN

;[arpa]	still in IFN FtCImp
;[arpa]	still in IFN FtCImp ;⊗ TTIMPI


;[arpa] SUBROUTINE TO HANDLE TTY INPUT TO CROSSPATCHED TTY

TTIMPI:
	PUSHJ	P,RQTIIO##	;[arpa] REQUEST IMP PROCESSING OF TTY DATA
	SETZ	T1,		;[arpa] SIGNAL NOT A NORMAL BREAK CHAR
	POPJ	P,		;[arpa] RETURN

;[arpa]	still in IFN FtCImp
;[arpa]	still in IFN FtCImp ;⊗ TTYTTI

;[arpa] SUBROUTINE CALLED FROM IMP SERVICE TO GET A CHARACTER
;[arpa]   FROM THE INPUT BUFFER OF A CROSSPATCHED TTY.
;[arpa]   ENTER WITH LDB ADDRESS IN U.
;[arpa]   SKIP RETURNS 9-BIT CHAR IN T3.
;[arpa]   NON-SKIP RETURN IF NONE

TTYTTI::PUSH	P,S		;[arpa] IN CASE CLOCK1 REALLY CARES ABOUT S
	SETZ	S,		;[arpa] MAKE SURE TYI IS NOT FOOLED
	PUSHJ	P,TYI		;[arpa] GO GET THE CHARACTER
	 SKIPA			;[arpa] NONE LEFT
	  AOS	-1(P)		;[arpa] GOT A CHARACTER
	POP	P,S		;[arpa] RESTORE S
	POPJ	P,		;[arpa] AND RETURN

;[arpa]	still in IFN FtCImp
;[arpa]	still in IFN FtCImp ;⊗ TTYXMT

;[arpa] SUBROUTINE TO SEND A CHARACTER TO A TELETYPE BUFFER.

;[arpa] CALLED FROM IMP INTERRUPT LEVEL.
;[arpa]   ENTER WITH LDB ADDRESS IN U, CHAR IN T3.
;[arpa]   RETURN SKIP IF OK, NON-SKIP IF NO ROOM.

TTYXMT::HLL	U,LDBDCH(U)	;[arpa] GET CHARACTERISTICS
	MOVEI	T1,LDROSU	;[arpa] GET OSU BIT FIRST
	TDNE	T1,LDBDCH(U)	;[arpa] IS IT ON
	  PJRST	CPOPJ1##	;[arpa] YES - QUIT VERY QUICKLY
	MOVE	T1,TTFREN##	;[arpa] GET NO. OF CHUNKS AVAILABLE
	MOVE	T2,LDBTOC(U)	;[arpa] AND CHECK HOW MUCH NOW IN BUFFER
	CAIL	T1,3		;[arpa] ALWAYS LEAVE A LITTLE
	 CAML	T2,TIWRNN	;[arpa] AND DON'T GIVE TOO MUCH TO ONE TTY
	  POPJ	P,		;[arpa] TOO LITTLE OR TOO MUCH - TELL IMPSER TO STOP
	AOS	(P)		;[arpa] CONFIDENCE
	TRNN	T3,400		;[arpa] IMAGE CHARACTER?
	  PUSHJ	P,PEVEN8	;[arpa] NO - FIX PARITY
	PJRST	TYO9A		;[arpa] SEND, THEN GO BACK FOR MORE

;[arpa] STILL IN FTCIMP
;[arpa]	still in IFN FtCImp ;⊗ SETECH SETNEC

;[arpa] ROUTINES TO SET/CLEAR THE NOECHO BIT IN DEVIOS, DOING THE APPROPRIATE
;[arpa]  LINE HANDLING. SENDING TELNET CONTROL CODES, ETC.

;[arpa] 	MOVE	U, LINE ADDR
;[arpa] 	PUSHJ	P,SETECH (TO CLEAR NOECHO)
;[arpa] 		  SETNEC (TO SET NOECHO)
;[arpa]		ALWAYS RETURN HERE.  F, S CLOBBERED

SETECH::TDZA	S,S		;[arpa] HERE TO CLEAR THE BIT
SETNEC::MOVEI	S,IOSNEC	;[arpa] HERE TO SET THE BIT
	HRRZ	F,LDBDDB(U)	;[arpa] LOOK FOR THE ATTACHED TTY DDB
	JUMPE	F,UUOLDB	;[arpa] NOT AROUND (SHOULD NEVER HAPPEN)
	IORM	S,DEVIOS(F)	;[arpa] SET BIT IF SETTING
	XORI	S,IOSNEC	;[arpa] CLEAR BIT IF CLEARING (GETTIN' DIZZY)
	ANDCAB	S,DEVIOS(F)	;[arpa]
	PJRST	UUOLDB		;[arpa] MAKE LDB BITS AGREE WITH S BITS

> ;[arpa] END FTCIMP
	SUBTTL	IMPURE DATA ;⊗ ECHCNT TTBASE DSCNUM .GTSCN %SCNRI %SCNXI %SCNEI TIWRNN %SCNAL RPIMWN TTFTAK TTFPUT SCNMXL TIWRN1 SCNEND

	$LOW
ECHCNT:	0			;CLOCK REQUEST QUEUE COUNTER
TTBASE::0			;FIRST WORD IN TERMINAL BUFFER SPACE
IFN FTDIAL,<
DSCNUM:	BLOCK	2		;PHONE NUMBER BEING DIALLED, OR LAST DIALLED
>

.GTSCN::
;SCNSER RESPONSE DATA (%SC??? VALID ONLY IF FTRSP!FTACCT)
%SCNRI::0			;(0)  NUMBER OF CHARS (EXCLUDES MIC) RECEIVED
%SCNXI::0			;(1)  NUMBER OF CHARS (INCLUDES FILL) XMITTED
%SCNEI::0			;(2)  NUMBER OF CHARS ECHOED (SUBSET OF %SCNXI)
TIWRNN::EXP	TTIBRK		;(3)  MAX BUFFER SIZE
%SCNAL::0			;(4)  NUMBER OF ACTIVE LINES
RPIMWN::EXP	↑D600		;(5)  PIM BUFFER SIZE
	EXP	RECINT		;(6)  FOR MONITOR TEST
	EXP	XMTINT		;(7)  PROGRAMS
	EXP	0		;(10) WAS TYPEX
TTFTAK::0			;(11) FIRST FREE CHUNK
TTFPUT::0			;(12) LAST FREE CHUNK
SCNMXL==:<<.-.GTSCN-1>B26>
TIWRN1:	↑D80			;WORD TO SAVE OLD BUFFER LIMIT
	XLIST			;LITERALS UNDER XLIST
	$LIT
	LIST

SCNEND:	END